codemp/game/NPC.c File Reference

#include "b_local.h"
#include "anims.h"
#include "say.h"
#include "../icarus/Q3_Interface.h"

Go to the source code of this file.

Defines

#define REMOVE_DISTANCE   128
#define REMOVE_DISTANCE_SQR   (REMOVE_DISTANCE * REMOVE_DISTANCE)

Functions

void G_SoundOnEnt (gentity_t *ent, soundChannel_t channel, const char *soundPath)
void PM_SetTorsoAnimTimer (gentity_t *ent, int *torsoAnimTimer, int time)
void PM_SetLegsAnimTimer (gentity_t *ent, int *legsAnimTimer, int time)
void NPC_BSNoClip (void)
void G_AddVoiceEvent (gentity_t *self, int event, int speakDebounceTime)
void NPC_ApplyRoff (void)
void NPC_TempLookTarget (gentity_t *self, int lookEntNum, int minLookTime, int maxLookTime)
void NPC_CheckPlayerAim (void)
void NPC_CheckAllClear (void)
qboolean NPC_CheckLookTarget (gentity_t *self)
void NPC_SetLookTarget (gentity_t *self, int entNum, int clearTime)
void Mark1_dying (gentity_t *self)
void NPC_BSCinematic (void)
int GetTime (int lastTime)
void NPC_BSGM_Default (void)
void NPC_CheckCharmed (void)
qboolean Boba_Flying (gentity_t *self)
void NPC_SetAnim (gentity_t *ent, int type, int anim, int priority)
void pitch_roll_for_slope (gentity_t *forwhom, vec3_t pass_slope)
void GM_Dying (gentity_t *self)
void CorpsePhysics (gentity_t *self)
void NPC_RemoveBody (gentity_t *self)
int BodyRemovalPadTime (gentity_t *ent)
void SetNPCGlobals (gentity_t *ent)
void SaveNPCGlobals (void)
void RestoreNPCGlobals (void)
void ClearNPCGlobals (void)
void G_Cube (vec3_t mins, vec3_t maxs, vec3_t color, float alpha)
void G_Line (vec3_t start, vec3_t end, vec3_t color, float alpha)
void G_Cylinder (vec3_t start, vec3_t end, float radius, vec3_t color)
void NPC_ShowDebugInfo (void)
void NPC_ApplyScriptFlags (void)
void Q3_DebugPrint (int level, const char *format,...)
void NPC_HandleAIFlags (void)
void NPC_AvoidWallsAndCliffs (void)
void NPC_CheckAttackScript (void)
float NPC_MaxDistSquaredForWeapon (void)
void NPC_CheckAttackHold (void)
void NPC_KeepCurrentFacing (void)
void NPC_BehaviorSet_Charmed (int bState)
void NPC_BehaviorSet_Default (int bState)
void NPC_BehaviorSet_Interrogator (int bState)
void NPC_BSImperialProbe_Attack (void)
void NPC_BSImperialProbe_Patrol (void)
void NPC_BSImperialProbe_Wait (void)
void NPC_BehaviorSet_ImperialProbe (int bState)
void NPC_BSSeeker_Default (void)
void NPC_BehaviorSet_Seeker (int bState)
void NPC_BSRemote_Default (void)
void NPC_BehaviorSet_Remote (int bState)
void NPC_BSSentry_Default (void)
void NPC_BehaviorSet_Sentry (int bState)
void NPC_BehaviorSet_Grenadier (int bState)
void NPC_BehaviorSet_Sniper (int bState)
void NPC_BehaviorSet_Stormtrooper (int bState)
void NPC_BehaviorSet_Jedi (int bState)
void NPC_BehaviorSet_Droid (int bState)
void NPC_BehaviorSet_Mark1 (int bState)
void NPC_BehaviorSet_Mark2 (int bState)
void NPC_BehaviorSet_ATST (int bState)
void NPC_BehaviorSet_MineMonster (int bState)
void NPC_BehaviorSet_Howler (int bState)
void NPC_BehaviorSet_Rancor (int bState)
void NPC_BSEmplaced (void)
qboolean NPC_CheckSurrender (void)
void Boba_FlyStop (gentity_t *self)
void NPC_BSWampa_Default (void)
void NPC_RunBehavior (int team, int bState)
void NPC_ExecuteBState (gentity_t *self)
void NPC_CheckInSolid (void)
void G_DroidSounds (gentity_t *self)
void NPC_Think (gentity_t *self)
void NPC_InitAI (void)
void NPC_InitGame (void)

Variables

vec3_t playerMins
vec3_t playerMaxs
vmCvar_t g_saberRealisticCombat
gentity_tNPC
gNPC_tNPCInfo
gclient_tclient
usercmd_t ucmd
visibility_t enemyVisibility
int eventClearTime
gentity_t_saved_NPC
gNPC_t_saved_NPCInfo
gclient_t_saved_client
usercmd_t _saved_ucmd
qboolean showBBoxes
vec3_t NPCDEBUG_RED = {1.0, 0.0, 0.0}
vec3_t NPCDEBUG_GREEN = {0.0, 1.0, 0.0}
vec3_t NPCDEBUG_BLUE = {0.0, 0.0, 1.0}
vec3_t NPCDEBUG_LIGHT_BLUE = {0.3f, 0.7f, 1.0}


Define Documentation

#define REMOVE_DISTANCE   128
 

Definition at line 112 of file NPC.c.

#define REMOVE_DISTANCE_SQR   (REMOVE_DISTANCE * REMOVE_DISTANCE)
 

Definition at line 113 of file NPC.c.


Function Documentation

qboolean Boba_Flying gentity_t self  ) 
 

Definition at line 386 of file NPC_AI_Jedi.c.

References gentity_s::client, EF2_FLYING, playerState_s::eFlags2, gentity_t, gclient_s::ps, and qboolean.

Referenced by NPC_RunBehavior().

00387 {
00388         return ((qboolean)(self->client->ps.eFlags2&EF2_FLYING));//moveType==MT_FLYSWIM));
00389 }

void Boba_FlyStop gentity_t self  ) 
 

Definition at line 367 of file NPC_AI_Jedi.c.

References gNPC_t::aiFlags, gentity_s::client, gentity_s::count, EF2_FLYING, playerState_s::eFlags2, g_gravity, gentity_t, playerState_s::gravity, gclient_s::jetPackTime, entityState_s::loopSound, gentity_s::NPC, NPCAI_CUSTOM_GRAVITY, gclient_s::ps, Q_irand(), gentity_s::s, TIMER_Set(), and vmCvar_t::value.

Referenced by player_die().

00368 {
00369         self->client->ps.gravity = g_gravity.value;
00370         if ( self->NPC )
00371         {
00372                 self->NPC->aiFlags &= ~NPCAI_CUSTOM_GRAVITY;
00373         }
00374         self->client->ps.eFlags2 &= ~EF2_FLYING;
00375         self->client->jetPackTime = 0;
00376         //stop jet loop sound
00377         self->s.loopSound = 0;
00378         if ( self->NPC )
00379         {
00380                 self->count = 0; // SEEKER shot ammo count
00381                 TIMER_Set( self, "jetRecharge", Q_irand( 1000, 5000 ) );
00382                 TIMER_Set( self, "jumpChaseDebounce", Q_irand( 500, 2000 ) );
00383         }
00384 }

int BodyRemovalPadTime gentity_t ent  ) 
 

Definition at line 233 of file NPC.c.

References CLASS_GONK, CLASS_INTERROGATOR, CLASS_MARK1, CLASS_MARK2, CLASS_MOUSE, CLASS_PROBE, CLASS_R2D2, CLASS_R5D2, CLASS_REMOTE, CLASS_SEEKER, CLASS_SENTRY, gentity_s::client, gentity_t, and gclient_s::NPC_class.

00234 {
00235         int     time;
00236 
00237         if ( !ent || !ent->client )
00238                 return 0;
00239 /*
00240         switch ( ent->client->playerTeam )
00241         {
00242         case NPCTEAM_KLINGON:   // no effect, we just remove them when the player isn't looking
00243         case NPCTEAM_SCAVENGERS:
00244         case NPCTEAM_HIROGEN:
00245         case NPCTEAM_MALON:
00246         case NPCTEAM_IMPERIAL:
00247         case NPCTEAM_STARFLEET:
00248                 time = 10000; // 15 secs.
00249                 break;
00250 
00251         case NPCTEAM_BORG:
00252                 time = 2000;
00253                 break;
00254 
00255         case NPCTEAM_STASIS:
00256                 return qtrue;
00257                 break;
00258 
00259         case NPCTEAM_FORGE:
00260                 time = 1000;
00261                 break;
00262 
00263         case NPCTEAM_BOTS:
00264 //              if (!Q_stricmp( ent->NPC_type, "mouse" ))
00265 //              {
00266                         time = 0;
00267 //              }
00268 //              else
00269 //              {
00270 //                      time = 10000;
00271 //              }
00272                 break;
00273 
00274         case NPCTEAM_8472:
00275                 time = 2000;
00276                 break;
00277 
00278         default:
00279                 // never go away
00280                 time = Q3_INFINITE;
00281                 break;
00282         }
00283 */
00284         // team no longer indicates species/race, so in this case we'd use NPC_class, but
00285         switch( ent->client->NPC_class )
00286         {
00287         case CLASS_MOUSE:
00288         case CLASS_GONK:
00289         case CLASS_R2D2:
00290         case CLASS_R5D2:
00291         //case CLASS_PROTOCOL:
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                 // never go away
00303         //      time = Q3_INFINITE;
00304                 // for now I'm making default 10000
00305                 time = 10000;
00306                 break;
00307 
00308         }
00309         
00310 
00311         return time;
00312 }

void ClearNPCGlobals void   ) 
 

Definition at line 647 of file NPC.c.

References client, NPC, NPCInfo, and NULL.

Referenced by G_RunFrame().

00648 {
00649         NPC = NULL;
00650         NPCInfo = NULL;
00651         client = NULL;
00652 }

void CorpsePhysics gentity_t self  ) 
 

Definition at line 46 of file NPC.c.

References AddSightEvent(), AEL_DISCOVERED, ALERT_CLEAR_TIME, CLASS_GALAKMECH, CLASS_INTERROGATOR, CLASS_MARK1, CLASS_PROTOCOL, gentity_s::client, ClientThink(), entityShared_t::contents, CONTENTS_CORPSE, CONTENTS_TRIGGER, entityShared_t::currentOrigin, EF_DISINTEGRATION, EF_NODRAW, playerState_s::eFlags, entityState_s::eFlags, gentity_s::enemy, ENTITYNUM_NONE, eventClearTime, g_dismember, g_saberRealisticCombat, gentity_t, GM_Dying(), playerState_s::groundEntityNum, vmCvar_t::integer, level, memset(), gentity_s::message, gclient_s::NPC_class, NULL, entityState_s::number, pitch_roll_for_slope(), gclient_s::ps, gentity_s::r, gclient_s::respawnTime, gentity_s::s, entityState_s::time, level_locals_t::time, and ucmd.

Referenced by NPC_RemoveBody().

00047 {
00048         // run the bot through the server like it was a real client
00049         memset( &ucmd, 0, sizeof( ucmd ) );
00050         ClientThink( self->s.number, &ucmd );
00051         //VectorCopy( self->s.origin, self->s.origin2 );
00052         //rww - don't get why this is happening.
00053         
00054         if ( self->client->NPC_class == CLASS_GALAKMECH )
00055         {
00056                 GM_Dying( self );
00057         }
00058         //FIXME: match my pitch and roll for the slope of my groundPlane
00059         if ( self->client->ps.groundEntityNum != ENTITYNUM_NONE && !(self->s.eFlags&EF_DISINTEGRATION) )
00060         {//on the ground
00061                 //FIXME: check 4 corners
00062                 pitch_roll_for_slope( self, NULL );
00063         }
00064 
00065         if ( eventClearTime == level.time + ALERT_CLEAR_TIME )
00066         {//events were just cleared out so add me again
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         {//been dead for 3 seconds
00075                 if ( g_dismember.integer < 11381138 && !g_saberRealisticCombat.integer )
00076                 {//can't be dismembered once dead
00077                         if ( self->client->NPC_class != CLASS_PROTOCOL )
00078                         {
00079                         //      self->client->dismembered = qtrue;
00080                         }
00081                 }
00082         }
00083 
00084         //if ( level.time - self->s.time > 500 )
00085         if (self->client->respawnTime < (level.time+500))
00086         {//don't turn "nonsolid" until about 1 second after actual death
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))   // The Mark1 & Interrogator stays solid.
00093                 {
00094                         self->r.contents = CONTENTS_CORPSE;
00095                         //self->r.maxs[2] = -8;
00096                 }
00097 
00098                 if ( self->message )
00099                 {
00100                         self->r.contents |= CONTENTS_TRIGGER;
00101                 }
00102         }
00103 }

void G_AddVoiceEvent gentity_t self,
int  event,
int  speakDebounceTime
 

Definition at line 23 of file NPC_sounds.c.

00024 {
00025         if ( !self->NPC )
00026         {
00027                 return;
00028         }
00029 
00030         if ( !self->client || self->client->ps.pm_type >= PM_DEAD )
00031         {
00032                 return;
00033         }
00034 
00035         if ( self->NPC->blockedSpeechDebounceTime > level.time )
00036         {
00037                 return;
00038         }
00039 
00040         if ( trap_ICARUS_TaskIDPending( self, TID_CHAN_VOICE ) )
00041         {
00042                 return;
00043         }
00044 
00045         
00046         if ( (self->NPC->scriptFlags&SCF_NO_COMBAT_TALK) && ( (event >= EV_ANGER1 && event <= EV_VICTORY3) || (event >= EV_CHASE1 && event <= EV_SUSPICIOUS5) ) )//(event < EV_FF_1A || event > EV_FF_3C) && (event < EV_RESPOND1 || event > EV_MISSION3) )
00047         {
00048                 return;
00049         }
00050         
00051         if ( (self->NPC->scriptFlags&SCF_NO_ALERT_TALK) && (event >= EV_GIVEUP1 && event <= EV_SUSPICIOUS5) )
00052         {
00053                 return;
00054         }
00055         //FIXME: Also needs to check for teammates. Don't want
00056         //              everyone babbling at once
00057 
00058         //NOTE: was losing too many speech events, so we do it directly now, screw networking!
00059         //G_AddEvent( self, event, 0 );
00060         G_SpeechEvent( self, event );
00061 
00062         //won't speak again for 5 seconds (unless otherwise specified)
00063         self->NPC->blockedSpeechDebounceTime = level.time + ((speakDebounceTime==0) ? 5000 : speakDebounceTime);
00064 }

void G_Cube vec3_t  mins,
vec3_t  maxs,
vec3_t  color,
float  alpha
 

Definition at line 16 of file g_nav.c.

00017 {
00018 
00019 }

void G_Cylinder vec3_t  start,
vec3_t  end,
float  radius,
vec3_t  color
 

void G_DroidSounds gentity_t self  ) 
 

Definition at line 1787 of file NPC.c.

References CHAN_AUTO, CLASS_GONK, CLASS_MOUSE, CLASS_PROBE, CLASS_R2D2, CLASS_R5D2, gentity_s::client, G_SoundOnEnt(), gentity_t, gclient_s::NPC_class, Q_irand(), TIMER_Done(), TIMER_Set(), and va().

Referenced by NPC_Think().

01788 {
01789         if ( self->client )
01790         {//make the noises
01791                 if ( TIMER_Done( self, "patrolNoise" ) && !Q_irand( 0, 20 ) )
01792                 {
01793                         switch( self->client->NPC_class )
01794                         {
01795                         case CLASS_R2D2:                                // droid
01796                                 G_SoundOnEnt(self, CHAN_AUTO, va("sound/chars/r2d2/misc/r2d2talk0%d.wav",Q_irand(1, 3)) );
01797                                 break;
01798                         case CLASS_R5D2:                                // droid
01799                                 G_SoundOnEnt(self, CHAN_AUTO, va("sound/chars/r5d2/misc/r5talk%d.wav",Q_irand(1, 4)) );
01800                                 break;
01801                         case CLASS_PROBE:                               // droid
01802                                 G_SoundOnEnt(self, CHAN_AUTO, va("sound/chars/probe/misc/probetalk%d.wav",Q_irand(1, 3)) );
01803                                 break;
01804                         case CLASS_MOUSE:                               // droid
01805                                 G_SoundOnEnt(self, CHAN_AUTO, va("sound/chars/mouse/misc/mousego%d.wav",Q_irand(1, 3)) );
01806                                 break;
01807                         case CLASS_GONK:                                // droid
01808                                 G_SoundOnEnt(self, CHAN_AUTO, va("sound/chars/gonk/misc/gonktalk%d.wav",Q_irand(1, 2)) );
01809                                 break;
01810                         }
01811                         TIMER_Set( self, "patrolNoise", Q_irand( 2000, 4000 ) );
01812                 }
01813         }
01814 }

void G_Line vec3_t  start,
vec3_t  end,
vec3_t  color,
float  alpha
 

Definition at line 11 of file g_nav.c.

References vec3_t.

00012 {
00013 
00014 }

void G_SoundOnEnt gentity_t ent,
soundChannel_t  channel,
const char *  soundPath
 

int GetTime int  lastTime  ) 
 

void GM_Dying gentity_t self  ) 
 

Definition at line 133 of file NPC_AI_GalakMech.c.

References gentity_s::client, entityShared_t::currentOrigin, playerState_s::electrifyTime, FRAMETIME, G_EffectIndex(), G_FreeEntity(), G_PlayEffectID(), gentity_t, gentity_s::ghoul2, renderInfo_s::headBolt, level, gentity_s::nextthink, NPC_SetSurfaceOnOff(), gclient_s::ps, Q_irand(), qfalse, qtrue, gentity_s::r, gclient_s::renderInfo, gentity_s::s, gentity_s::think, level_locals_t::time, entityState_s::time, TIMER_Done(), TIMER_Set(), trap_G2API_AddBolt(), trap_G2API_GetSurfaceRenderStatus(), TURN_OFF, and vec3_origin.

Referenced by CorpsePhysics().

00134 {
00135         if ( level.time - self->s.time < 4000 )
00136         {//FIXME: need a real effect
00137                 //self->s.powerups |= ( 1 << PW_SHOCKED );
00138                 //self->client->ps.powerups[PW_SHOCKED] = level.time + 1000;
00139                 self->client->ps.electrifyTime = level.time + 1000;
00140                 if ( TIMER_Done( self, "dyingExplosion" ) )
00141                 {
00142                         int     newBolt;
00143                         switch ( Q_irand( 1, 14 ) )
00144                         {
00145                         // Find place to generate explosion
00146                         case 1:
00147                                 if (!trap_G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "r_hand" ))
00148                                 {//r_hand still there
00149                                         GM_CreateExplosion( self, trap_G2API_AddBolt(self->ghoul2, 0, "*flasha"), qtrue );
00150                                         NPC_SetSurfaceOnOff( self, "r_hand", TURN_OFF );
00151                                 }
00152                                 else if (!trap_G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "r_arm_middle" ))
00153                                 {//r_arm_middle still there
00154                                         newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*r_arm_elbow" );
00155                                         NPC_SetSurfaceOnOff( self, "r_arm_middle", TURN_OFF );
00156                                 }
00157                                 break;
00158                         case 2:
00159                                 //FIXME: do only once?
00160                                 if (!trap_G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "l_hand" ))
00161                                 {//l_hand still there
00162                                         GM_CreateExplosion( self, trap_G2API_AddBolt(self->ghoul2, 0, "*flashc"), qfalse );
00163                                         NPC_SetSurfaceOnOff( self, "l_hand", TURN_OFF );
00164                                 }
00165                                 else if (!trap_G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "l_arm_wrist" ))
00166                                 {//l_arm_wrist still there
00167                                         newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*l_arm_cap_l_hand" );
00168                                         NPC_SetSurfaceOnOff( self, "l_arm_wrist", TURN_OFF );
00169                                 }
00170                                 else if (!trap_G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "l_arm_middle" ))
00171                                 {//l_arm_middle still there
00172                                         newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*l_arm_cap_l_hand" );
00173                                         NPC_SetSurfaceOnOff( self, "l_arm_middle", TURN_OFF );
00174                                 }
00175                                 else if (!trap_G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "l_arm_augment" ))
00176                                 {//l_arm_augment still there
00177                                         newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*l_arm_elbow" );
00178                                         NPC_SetSurfaceOnOff( self, "l_arm_augment", TURN_OFF );
00179                                 }
00180                                 break;
00181                         case 3:
00182                         case 4:
00183                                 newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*hip_fr" );
00184                                 GM_CreateExplosion( self, newBolt, qfalse );
00185                                 break;
00186                         case 5:
00187                         case 6:
00188                                 newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*shldr_l" );
00189                                 GM_CreateExplosion( self, newBolt, qfalse );
00190                                 break;
00191                         case 7:
00192                         case 8:
00193                                 newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*uchest_r" );
00194                                 GM_CreateExplosion( self, newBolt, qfalse );
00195                                 break;
00196                         case 9:
00197                         case 10:
00198                                 GM_CreateExplosion( self, self->client->renderInfo.headBolt, qfalse );
00199                                 break;
00200                         case 11:
00201                                 newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*l_leg_knee" );
00202                                 GM_CreateExplosion( self, newBolt, qtrue );
00203                                 break;
00204                         case 12:
00205                                 newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*r_leg_knee" );
00206                                 GM_CreateExplosion( self, newBolt, qtrue );
00207                                 break;
00208                         case 13:
00209                                 newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*l_leg_foot" );
00210                                 GM_CreateExplosion( self, newBolt, qtrue );
00211                                 break;
00212                         case 14:
00213                                 newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*r_leg_foot" );
00214                                 GM_CreateExplosion( self, newBolt, qtrue );
00215                                 break;
00216                         }
00217 
00218                         TIMER_Set( self, "dyingExplosion", Q_irand( 300, 1100 ) );
00219                 }
00220         }
00221         else
00222         {//one final, huge explosion
00223                 G_PlayEffectID( G_EffectIndex("galak/explode"), self->r.currentOrigin, vec3_origin );
00224 //              G_PlayEffect( "small_chunks", self->r.currentOrigin );
00225 //              G_PlayEffect( "env/exp_trail_comp", self->r.currentOrigin, self->currentAngles );
00226                 self->nextthink = level.time + FRAMETIME;
00227                 self->think = G_FreeEntity;
00228         }
00229 }

void Mark1_dying gentity_t self  ) 
 

Definition at line 250 of file NPC_AI_Mark1.c.

References gentity_s::client, gentity_t, gentity_s::ghoul2, Mark1Dead_FireBlaster(), Mark1Dead_FireRocket(), NPC_Mark1_Part_Explode(), NPC_SetSurfaceOnOff(), gclient_s::ps, Q_irand(), RestoreNPCGlobals(), SaveNPCGlobals(), SetNPCGlobals(), TIMER_Done(), TIMER_Set(), playerState_s::torsoTimer, trap_G2API_AddBolt(), trap_G2API_GetSurfaceRenderStatus(), TURN_OFF, and va().

Referenced by NPC_RemoveBody().

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                         // Find place to generate explosion
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 //              int             dir;
00280 //              vec3_t  right;
00281 
00282                 // Shove to the side
00283 //              AngleVectors( self->client->renderInfo.eyeAngles, NULL, right, NULL );
00284 //              VectorMA( self->client->ps.velocity, -80, right, self->client->ps.velocity );
00285 
00286                 // See which weapons are there
00287                 // Randomly fire blaster
00288                 if (!trap_G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "l_arm" ))     // Is the blaster still on the model?
00289                 {
00290                         if (Q_irand( 1, 5) == 1)
00291                         {
00292                                 SaveNPCGlobals();
00293                                 SetNPCGlobals( self );
00294                                 Mark1Dead_FireBlaster();
00295                                 RestoreNPCGlobals();
00296                         }
00297                 }
00298 
00299                 // Randomly fire rocket
00300                 if (!trap_G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "r_arm" ))     // Is the rocket still on the model?
00301                 {
00302                         if (Q_irand( 1, 10) == 1)
00303                         {
00304                                 SaveNPCGlobals();
00305                                 SetNPCGlobals( self );
00306                                 Mark1Dead_FireRocket();
00307                                 RestoreNPCGlobals();
00308                         }
00309                 }
00310         }
00311 
00312 }

void NPC_ApplyRoff void   ) 
 

Definition at line 497 of file NPC_move.c.

References BG_PlayerStateToEntityState(), gentity_s::client, NPC, gclient_s::ps, qfalse, gentity_s::s, and trap_LinkEntity().

Referenced by NPC_ExecuteBState(), and NPC_Think().

00498 {
00499         BG_PlayerStateToEntityState( &NPC->client->ps, &NPC->s, qfalse );
00500         //VectorCopy ( NPC->r.currentOrigin, NPC->lastOrigin );
00501         //rwwFIXMEFIXME: Any significance to this?
00502 
00503         // use the precise origin for linking
00504         trap_LinkEntity(NPC);
00505 }

void NPC_ApplyScriptFlags void   ) 
 

Definition at line 683 of file NPC.c.

References BUTTON_ALT_ATTACK, BUTTON_ATTACK, BUTTON_USE, BUTTON_WALKING, usercmd_s::buttons, gNPC_t::charmedTime, usercmd_s::forwardmove, level, NPCInfo, usercmd_s::rightmove, SCF_ALT_FIRE, SCF_CROUCHED, SCF_LEAN_LEFT, SCF_LEAN_RIGHT, SCF_RUNNING, SCF_WALKING, gNPC_t::scriptFlags, level_locals_t::time, ucmd, and usercmd_s::upmove.

Referenced by NPC_ExecuteBState().

00684 {
00685         if ( NPCInfo->scriptFlags & SCF_CROUCHED )
00686         {
00687                 if ( NPCInfo->charmedTime > level.time && (ucmd.forwardmove || ucmd.rightmove) )
00688                 {//ugh, if charmed and moving, ignore the crouched command
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                 {//ugh, if charmed and moving, ignore the walking command
00704                 }
00705                 else
00706                 {
00707                         ucmd.buttons |= BUTTON_WALKING;
00708                 }
00709         }
00710 /*
00711         if(NPCInfo->scriptFlags & SCF_CAREFUL)
00712         {
00713                 ucmd.buttons |= BUTTON_CAREFUL;
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         {//Use altfire instead
00733                 ucmd.buttons |= BUTTON_ALT_ATTACK;
00734         }
00735 }

void NPC_AvoidWallsAndCliffs void   ) 
 

Definition at line 835 of file NPC.c.

Referenced by NPC_ExecuteBState().

00836 {
00837         //...
00838 }

void NPC_BehaviorSet_ATST int  bState  ) 
 

Definition at line 1293 of file NPC.c.

References BS_DEFAULT, BS_HUNT_AND_KILL, BS_PATROL, BS_STAND_AND_SHOOT, NPC_BehaviorSet_Default(), and NPC_BSATST_Default().

Referenced by NPC_RunBehavior().

01294 {
01295         switch( bState )
01296         {
01297         case BS_DEFAULT:
01298         case BS_PATROL:
01299         case BS_STAND_AND_SHOOT:
01300         case BS_HUNT_AND_KILL:
01301                 NPC_BSATST_Default();
01302                 break;
01303         default:
01304                 NPC_BehaviorSet_Default( bState );
01305                 break;
01306         }
01307 }

void NPC_BehaviorSet_Charmed int  bState  ) 
 

Definition at line 939 of file NPC.c.

References BS_DEFAULT, BS_FLEE, BS_FOLLOW_LEADER, BS_REMOVE, BS_SEARCH, BS_WANDER, NPC_BSDefault(), NPC_BSFlee(), NPC_BSFollowLeader(), NPC_BSRemove(), NPC_BSSearch(), and NPC_BSWander().

Referenced by NPC_RunBehavior().

00940 {
00941         switch( bState )
00942         {
00943         case BS_FOLLOW_LEADER://# 40: Follow your leader and shoot any enemies you come across
00944                 NPC_BSFollowLeader();
00945                 break;
00946         case BS_REMOVE:
00947                 NPC_BSRemove();
00948                 break;
00949         case BS_SEARCH:                 //# 43: Using current waypoint as a base, search the immediate branches of waypoints for enemies
00950                 NPC_BSSearch();
00951                 break;
00952         case BS_WANDER:                 //# 46: Wander down random waypoint paths
00953                 NPC_BSWander();
00954                 break;
00955         case BS_FLEE:
00956                 NPC_BSFlee();
00957                 break;
00958         default:
00959         case BS_DEFAULT://whatever
00960                 NPC_BSDefault();
00961                 break;
00962         }
00963 }

void NPC_BehaviorSet_Default int  bState  ) 
 

Definition at line 970 of file NPC.c.

References BS_ADVANCE_FIGHT, BS_CINEMATIC, BS_DEFAULT, BS_FLEE, BS_FOLLOW_LEADER, BS_JUMP, BS_NOCLIP, BS_REMOVE, BS_SEARCH, BS_SLEEP, BS_WAIT, BS_WANDER, NPC_BSAdvanceFight(), NPC_BSCinematic(), NPC_BSDefault(), NPC_BSFlee(), NPC_BSFollowLeader(), NPC_BSJump(), NPC_BSNoClip(), NPC_BSRemove(), NPC_BSSearch(), NPC_BSSleep(), NPC_BSWait(), and NPC_BSWander().

Referenced by NPC_BehaviorSet_ATST(), NPC_BehaviorSet_Droid(), NPC_BehaviorSet_Grenadier(), NPC_BehaviorSet_Howler(), NPC_BehaviorSet_ImperialProbe(), NPC_BehaviorSet_Interrogator(), NPC_BehaviorSet_Jedi(), NPC_BehaviorSet_Mark1(), NPC_BehaviorSet_Mark2(), NPC_BehaviorSet_MineMonster(), NPC_BehaviorSet_Rancor(), NPC_BehaviorSet_Seeker(), NPC_BehaviorSet_Sentry(), NPC_BehaviorSet_Sniper(), NPC_BehaviorSet_Stormtrooper(), and NPC_RunBehavior().

00971 {
00972         switch( bState )
00973         {
00974         case BS_ADVANCE_FIGHT://head toward captureGoal, shoot anything that gets in the way
00975                 NPC_BSAdvanceFight ();
00976                 break;
00977         case BS_SLEEP://Follow a path, looking for enemies
00978                 NPC_BSSleep ();
00979                 break;
00980         case BS_FOLLOW_LEADER://# 40: Follow your leader and shoot any enemies you come across
00981                 NPC_BSFollowLeader();
00982                 break;
00983         case BS_JUMP:                   //41: Face navgoal and jump to it.
00984                 NPC_BSJump();
00985                 break;
00986         case BS_REMOVE:
00987                 NPC_BSRemove();
00988                 break;
00989         case BS_SEARCH:                 //# 43: Using current waypoint as a base, search the immediate branches of waypoints for enemies
00990                 NPC_BSSearch();
00991                 break;
00992         case BS_NOCLIP:
00993                 NPC_BSNoClip();
00994                 break;
00995         case BS_WANDER:                 //# 46: Wander down random waypoint paths
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://whatever
01009                 NPC_BSDefault();
01010                 break;
01011         }
01012 }

void NPC_BehaviorSet_Droid int  bState  ) 
 

Definition at line 1232 of file NPC.c.

References BS_DEFAULT, BS_PATROL, BS_STAND_GUARD, NPC_BehaviorSet_Default(), and NPC_BSDroid_Default().

Referenced by NPC_RunBehavior().

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 }

void NPC_BehaviorSet_Grenadier int  bState  ) 
 

Definition at line 1128 of file NPC.c.

References BS_DEFAULT, BS_HUNT_AND_KILL, BS_PATROL, BS_STAND_AND_SHOOT, BS_STAND_GUARD, NPC_BehaviorSet_Default(), and NPC_BSGrenadier_Default().

Referenced by NPC_RunBehavior().

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 }

void NPC_BehaviorSet_Howler int  bState  ) 
 

Definition at line 1336 of file NPC.c.

References BS_DEFAULT, BS_HUNT_AND_KILL, BS_PATROL, BS_STAND_AND_SHOOT, BS_STAND_GUARD, NPC_BehaviorSet_Default(), and NPC_BSHowler_Default().

Referenced by NPC_RunBehavior().

01337 {
01338         switch( bState )
01339         {
01340         case BS_STAND_GUARD:
01341         case BS_PATROL:
01342         case BS_STAND_AND_SHOOT:
01343         case BS_HUNT_AND_KILL:
01344         case BS_DEFAULT:
01345                 NPC_BSHowler_Default();
01346                 break;
01347         default:
01348                 NPC_BehaviorSet_Default( bState );
01349                 break;
01350         }
01351 }

void NPC_BehaviorSet_ImperialProbe int  bState  ) 
 

Definition at line 1045 of file NPC.c.

References BS_DEFAULT, BS_HUNT_AND_KILL, BS_PATROL, BS_STAND_AND_SHOOT, BS_STAND_GUARD, NPC_BehaviorSet_Default(), and NPC_BSImperialProbe_Default().

Referenced by NPC_RunBehavior().

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 }

void NPC_BehaviorSet_Interrogator int  bState  ) 
 

Definition at line 1019 of file NPC.c.

References BS_DEFAULT, BS_HUNT_AND_KILL, BS_PATROL, BS_STAND_AND_SHOOT, BS_STAND_GUARD, NPC_BehaviorSet_Default(), and NPC_BSInterrogator_Default().

Referenced by NPC_RunBehavior().

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 }

void NPC_BehaviorSet_Jedi int  bState  ) 
 

Definition at line 1205 of file NPC.c.

References BS_DEFAULT, BS_FOLLOW_LEADER, BS_HUNT_AND_KILL, BS_PATROL, BS_STAND_AND_SHOOT, BS_STAND_GUARD, NPC_BehaviorSet_Default(), NPC_BSJedi_Default(), and NPC_BSJedi_FollowLeader().

Referenced by NPC_RunBehavior().

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 }

void NPC_BehaviorSet_Mark1 int  bState  ) 
 

Definition at line 1252 of file NPC.c.

References BS_DEFAULT, BS_PATROL, BS_STAND_GUARD, NPC_BehaviorSet_Default(), and NPC_BSMark1_Default().

Referenced by NPC_RunBehavior().

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 }

void NPC_BehaviorSet_Mark2 int  bState  ) 
 

Definition at line 1272 of file NPC.c.

References BS_DEFAULT, BS_HUNT_AND_KILL, BS_PATROL, BS_STAND_AND_SHOOT, NPC_BehaviorSet_Default(), and NPC_BSMark2_Default().

Referenced by NPC_RunBehavior().

01273 {
01274         switch( bState )
01275         {
01276         case BS_DEFAULT:
01277         case BS_PATROL:
01278         case BS_STAND_AND_SHOOT:
01279         case BS_HUNT_AND_KILL:
01280                 NPC_BSMark2_Default();
01281                 break;
01282         default:
01283                 NPC_BehaviorSet_Default( bState );
01284                 break;
01285         }
01286 }

void NPC_BehaviorSet_MineMonster int  bState  ) 
 

Definition at line 1314 of file NPC.c.

References BS_DEFAULT, BS_HUNT_AND_KILL, BS_PATROL, BS_STAND_AND_SHOOT, BS_STAND_GUARD, NPC_BehaviorSet_Default(), and NPC_BSMineMonster_Default().

Referenced by NPC_RunBehavior().

01315 {
01316         switch( bState )
01317         {
01318         case BS_STAND_GUARD:
01319         case BS_PATROL:
01320         case BS_STAND_AND_SHOOT:
01321         case BS_HUNT_AND_KILL:
01322         case BS_DEFAULT:
01323                 NPC_BSMineMonster_Default();
01324                 break;
01325         default:
01326                 NPC_BehaviorSet_Default( bState );
01327                 break;
01328         }
01329 }

void NPC_BehaviorSet_Rancor int  bState  ) 
 

Definition at line 1358 of file NPC.c.

References BS_DEFAULT, BS_HUNT_AND_KILL, BS_PATROL, BS_STAND_AND_SHOOT, BS_STAND_GUARD, NPC_BehaviorSet_Default(), and NPC_BSRancor_Default().

Referenced by NPC_RunBehavior().

01359 {
01360         switch( bState )
01361         {
01362         case BS_STAND_GUARD:
01363         case BS_PATROL:
01364         case BS_STAND_AND_SHOOT:
01365         case BS_HUNT_AND_KILL:
01366         case BS_DEFAULT:
01367                 NPC_BSRancor_Default();
01368                 break;
01369         default:
01370                 NPC_BehaviorSet_Default( bState );
01371                 break;
01372         }
01373 }

void NPC_BehaviorSet_Remote int  bState  ) 
 

Definition at line 1094 of file NPC.c.

References NPC_BSRemote_Default().

Referenced by NPC_RunBehavior().

01095 {
01096         NPC_BSRemote_Default();
01097 }

void NPC_BehaviorSet_Seeker int  bState  ) 
 

Definition at line 1070 of file NPC.c.

References BS_DEFAULT, BS_HUNT_AND_KILL, BS_PATROL, BS_STAND_AND_SHOOT, BS_STAND_GUARD, NPC_BehaviorSet_Default(), and NPC_BSSeeker_Default().

Referenced by NPC_RunBehavior().

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 }

void NPC_BehaviorSet_Sentry int  bState  ) 
 

Definition at line 1106 of file NPC.c.

References BS_DEFAULT, BS_HUNT_AND_KILL, BS_PATROL, BS_STAND_AND_SHOOT, BS_STAND_GUARD, NPC_BehaviorSet_Default(), and NPC_BSSentry_Default().

Referenced by NPC_RunBehavior().

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 }

void NPC_BehaviorSet_Sniper int  bState  ) 
 

Definition at line 1150 of file NPC.c.

References BS_DEFAULT, BS_HUNT_AND_KILL, BS_PATROL, BS_STAND_AND_SHOOT, BS_STAND_GUARD, NPC_BehaviorSet_Default(), and NPC_BSSniper_Default().

Referenced by NPC_RunBehavior().

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 }

void NPC_BehaviorSet_Stormtrooper int  bState  ) 
 

Definition at line 1173 of file NPC.c.

References BS_DEFAULT, BS_HUNT_AND_KILL, BS_INVESTIGATE, BS_PATROL, BS_SLEEP, BS_STAND_AND_SHOOT, BS_STAND_GUARD, NPC_BehaviorSet_Default(), NPC_BSST_Default(), NPC_BSST_Investigate(), and NPC_BSST_Sleep().

Referenced by NPC_RunBehavior().

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 }

void NPC_BSCinematic void   ) 
 

Definition at line 213 of file NPC_behavior.c.

References CalcEntitySpot(), gNPC_t::desiredPitch, gNPC_t::desiredYaw, gNPC_t::lockedDesiredPitch, gNPC_t::lockedDesiredYaw, NPC, NPC_MoveToGoal(), NPC_UpdateAngles(), NPCInfo, PITCH, qtrue, SCF_FIRE_WEAPON, gNPC_t::scriptFlags, SPOT_HEAD_LEAN, UpdateGoal(), vec3_t, vectoangles(), VectorSubtract, gNPC_t::watchTarget, WeaponThink(), and YAW.

Referenced by NPC_BehaviorSet_Default(), and NPC_RunBehavior().

00214 {
00215 
00216         if( NPCInfo->scriptFlags & SCF_FIRE_WEAPON )
00217         {
00218                 WeaponThink( qtrue );
00219         }
00220 
00221         if ( UpdateGoal() )
00222         {//have a goalEntity
00223                 //move toward goal, should also face that goal
00224                 NPC_MoveToGoal( qtrue );
00225         }
00226 
00227         if ( NPCInfo->watchTarget )
00228         {//have an entity which we want to keep facing
00229                 //NOTE: this will override any angles set by NPC_MoveToGoal
00230                 vec3_t eyes, viewSpot, viewvec, viewangles;
00231 
00232                 CalcEntitySpot( NPC, SPOT_HEAD_LEAN, eyes );
00233                 CalcEntitySpot( NPCInfo->watchTarget, SPOT_HEAD_LEAN, viewSpot );
00234 
00235                 VectorSubtract( viewSpot, eyes, viewvec );
00236                 
00237                 vectoangles( viewvec, viewangles );
00238 
00239                 NPCInfo->lockedDesiredYaw = NPCInfo->desiredYaw = viewangles[YAW];
00240                 NPCInfo->lockedDesiredPitch = NPCInfo->desiredPitch = viewangles[PITCH];
00241         }
00242 
00243         NPC_UpdateAngles( qtrue, qtrue );
00244 }

void NPC_BSEmplaced void   ) 
 

Definition at line 1650 of file NPC_behavior.c.

References entityState_s::angles, entityShared_t::currentOrigin, gNPC_t::desiredPitch, gNPC_t::desiredYaw, gentity_s::enemy, gNPC_t::enemyLastSeenLocation, g_entities, gentity_t, level, NPC, NPC_AimAdjust(), NPC_CheckEnemyExt(), NPC_ClearLOS4(), NPC_FaceEnemy(), NPC_ShotEntity(), NPC_UpdateAngles(), NPCInfo, entityState_s::number, gentity_s::painDebounceTime, Q_irand(), qboolean, qfalse, qtrue, gentity_s::r, gentity_s::s, SCF_DONT_FIRE, SCF_FIRE_WEAPON, gNPC_t::scriptFlags, gentity_s::takedamage, level_locals_t::time, vec3_t, VectorCopy, entityState_s::weapon, WeaponThink(), and WP_SABER.

Referenced by NPC_RunBehavior().

01651 {
01652         qboolean enemyLOS = qfalse;
01653         qboolean enemyCS = qfalse;
01654         qboolean faceEnemy = qfalse;
01655         qboolean shoot = qfalse;
01656         vec3_t  impactPos;
01657 
01658         //Don't do anything if we're hurt
01659         if ( NPC->painDebounceTime > level.time )
01660         {
01661                 NPC_UpdateAngles( qtrue, qtrue );
01662                 return;
01663         }
01664 
01665         if( NPCInfo->scriptFlags & SCF_FIRE_WEAPON )
01666         {
01667                 WeaponThink( qtrue );
01668         }
01669 
01670         //If we don't have an enemy, just idle
01671         if ( NPC_CheckEnemyExt(qfalse) == qfalse )
01672         {
01673                 if ( !Q_irand( 0, 30 ) )
01674                 {
01675                         NPCInfo->desiredYaw = NPC->s.angles[1] + Q_irand( -90, 90 );
01676                 }
01677                 if ( !Q_irand( 0, 30 ) )
01678                 {
01679                         NPCInfo->desiredPitch = Q_irand( -20, 20 );
01680                 }
01681                 NPC_UpdateAngles( qtrue, qtrue );
01682                 return;
01683         }
01684 
01685         if ( NPC_ClearLOS4( NPC->enemy ) )
01686         {
01687                 int hit;
01688                 gentity_t *hitEnt;
01689 
01690                 enemyLOS = qtrue;
01691 
01692                 hit = NPC_ShotEntity( NPC->enemy, impactPos );
01693                 hitEnt = &g_entities[hit];
01694 
01695                 if ( hit == NPC->enemy->s.number || ( hitEnt && hitEnt->takedamage ) )
01696                 {//can hit enemy or will hit glass or other minor breakable (or in emplaced gun), so shoot anyway
01697                         enemyCS = qtrue;
01698                         NPC_AimAdjust( 2 );//adjust aim better longer we have clear shot at enemy
01699                         VectorCopy( NPC->enemy->r.currentOrigin, NPCInfo->enemyLastSeenLocation );
01700                 }
01701         }
01702 /*
01703         else if ( trap_InPVS( NPC->enemy->r.currentOrigin, NPC->r.currentOrigin ) )
01704         {
01705                 NPCInfo->enemyLastSeenTime = level.time;
01706                 faceEnemy = qtrue;
01707                 NPC_AimAdjust( -1 );//adjust aim worse longer we cannot see enemy
01708         }
01709 */
01710 
01711         if ( enemyLOS )
01712         {//FIXME: no need to face enemy if we're moving to some other goal and he's too far away to shoot?
01713                 faceEnemy = qtrue;
01714         }
01715         if ( enemyCS )
01716         {
01717                 shoot = qtrue;
01718         }
01719 
01720         if ( faceEnemy )
01721         {//face the enemy
01722                 NPC_FaceEnemy( qtrue );
01723         }
01724         else
01725         {//we want to face in the dir we're running
01726                 NPC_UpdateAngles( qtrue, qtrue );
01727         }
01728 
01729         if ( NPCInfo->scriptFlags & SCF_DONT_FIRE )
01730         {
01731                 shoot = qfalse;
01732         }
01733 
01734         if ( NPC->enemy && NPC->enemy->enemy )
01735         {
01736                 if ( NPC->enemy->s.weapon == WP_SABER && NPC->enemy->enemy->s.weapon == WP_SABER )
01737                 {//don't shoot at an enemy jedi who is fighting another jedi, for fear of injuring one or causing rogue blaster deflections (a la Obi Wan/Vader duel at end of ANH)
01738                         shoot = qfalse;
01739                 }
01740         }
01741         if ( shoot )
01742         {//try to shoot if it's time
01743                 if( !(NPCInfo->scriptFlags & SCF_FIRE_WEAPON) ) // we've already fired, no need to do it again here
01744                 {
01745                         WeaponThink( qtrue );
01746                 }
01747         }
01748 }

void NPC_BSGM_Default void   ) 
 

Definition at line 1231 of file NPC_AI_GalakMech.c.

References gentity_s::client, gentity_s::clipmask, playerState_s::crouchheight, entityShared_t::currentOrigin, gentity_s::enemy, FL_SHIELDED, gentity_s::flags, GALAK_SHIELD_HEALTH, GENERATOR_HEALTH, HL_GENERIC1, gNPC_t::investigateCount, gNPC_t::investigateDebounceTime, level, gentity_s::locationDamage, entityShared_t::maxs, entityShared_t::mins, NPC, NPC_BSGM_Attack(), NPC_BSGM_Patrol(), NPC_SetSurfaceOnOff(), NPCInfo, entityState_s::number, gclient_s::ps, qtrue, gentity_s::r, gentity_s::s, SCF_FIRE_WEAPON, gNPC_t::scriptFlags, playerState_s::standheight, trace_t::startsolid, STAT_ARMOR, playerState_s::stats, level_locals_t::time, trap_Trace(), TURN_OFF, TURN_ON, VectorCopy, VectorSet, and WeaponThink().

Referenced by NPC_RunBehavior().

01232 {
01233         if( NPCInfo->scriptFlags & SCF_FIRE_WEAPON )
01234         {
01235                 WeaponThink( qtrue );
01236         }
01237         
01238         if ( NPC->client->ps.stats[STAT_ARMOR] <= 0 )
01239         {//armor gone
01240         //      if ( !NPCInfo->investigateDebounceTime )
01241                 if (0)
01242                 {//start regenerating the armor
01243                         NPC_SetSurfaceOnOff( NPC, "torso_shield", TURN_OFF );
01244                         NPC->flags &= ~FL_SHIELDED;//no more reflections
01245                         VectorSet( NPC->r.mins, -20, -20, -24 );
01246                         VectorSet( NPC->r.maxs, 20, 20, 64 );
01247                         NPC->client->ps.crouchheight = NPC->client->ps.standheight = 64;
01248                         if ( NPC->locationDamage[HL_GENERIC1] < GENERATOR_HEALTH )
01249                         {//still have the generator bolt-on
01250                                 if ( NPCInfo->investigateCount < 12 )
01251                                 {
01252                                         NPCInfo->investigateCount++;
01253                                 }
01254                                 NPCInfo->investigateDebounceTime = level.time + (NPCInfo->investigateCount * 5000);
01255                         }
01256                 }
01257                 else if ( NPCInfo->investigateDebounceTime < level.time )
01258                 {//armor regenerated, turn shield back on
01259                         //do a trace and make sure we can turn this back on?
01260                         trace_t tr;
01261                         trap_Trace( &tr, NPC->r.currentOrigin, shieldMins, shieldMaxs, NPC->r.currentOrigin, NPC->s.number, NPC->clipmask );
01262                         if ( !tr.startsolid )
01263                         {
01264                                 VectorCopy( shieldMins, NPC->r.mins );
01265                                 VectorCopy( shieldMaxs, NPC->r.maxs );
01266                                 NPC->client->ps.crouchheight = NPC->client->ps.standheight = shieldMaxs[2];
01267                                 NPC->client->ps.stats[STAT_ARMOR] = GALAK_SHIELD_HEALTH;
01268                                 NPCInfo->investigateDebounceTime = 0;
01269                                 NPC->flags |= FL_SHIELDED;//reflect normal shots
01270                         //      NPC->fx_time = level.time;
01271                                 NPC_SetSurfaceOnOff( NPC, "torso_shield", TURN_ON );
01272                         }
01273                 }
01274         }
01275         /*
01276         if ( NPC->client->ps.stats[STAT_ARMOR] > 0 )
01277         {//armor present
01278                 NPC->client->ps.powerups[PW_GALAK_SHIELD] = Q3_INFINITE;//temp, for effect
01279                 NPC_SetSurfaceOnOff( NPC, "torso_shield", TURN_ON );
01280         }
01281         else
01282         {
01283                 NPC_SetSurfaceOnOff( NPC, "torso_shield", TURN_OFF );
01284         }
01285         */
01286         //rwwFIXMEFIXME: Allow this stuff, and again, going to have to let the client know about it.
01287         //Maybe a surface-off bitflag of some sort in the entity state?
01288 
01289         if( !NPC->enemy )
01290         {//don't have an enemy, look for one
01291                 NPC_BSGM_Patrol();
01292         }
01293         else //if ( NPC->enemy )
01294         {//have an enemy
01295                 NPC_BSGM_Attack();
01296         }
01297 }

void NPC_BSImperialProbe_Attack void   ) 
 

void NPC_BSImperialProbe_Patrol void   ) 
 

void NPC_BSImperialProbe_Wait void   ) 
 

void NPC_BSNoClip void   ) 
 

Definition at line 1160 of file NPC_behavior.c.

References AngleVectors(), gentity_s::client, entityShared_t::currentAngles, entityShared_t::currentOrigin, gNPC_t::desiredYaw, DotProduct, floor(), usercmd_s::forwardmove, gNPC_t::goalEntity, NPC, NPC_UpdateAngles(), NPCInfo, NULL, gclient_s::ps, qtrue, gentity_s::r, usercmd_s::rightmove, ucmd, UpdateGoal(), usercmd_s::upmove, vec3_t, vectoangles(), VectorClear, VectorNormalize(), VectorSubtract, playerState_s::velocity, and YAW.

Referenced by NPC_BehaviorSet_Default().

01161 {
01162         if ( UpdateGoal() )
01163         {
01164                 vec3_t  dir, forward, right, angles, up = {0, 0, 1};
01165                 float   fDot, rDot, uDot;
01166 
01167                 VectorSubtract( NPCInfo->goalEntity->r.currentOrigin, NPC->r.currentOrigin, dir );
01168                 
01169                 vectoangles( dir, angles );
01170                 NPCInfo->desiredYaw = angles[YAW];
01171 
01172                 AngleVectors( NPC->r.currentAngles, forward, right, NULL );
01173 
01174                 VectorNormalize( dir );
01175 
01176                 fDot = DotProduct(forward, dir) * 127;
01177                 rDot = DotProduct(right, dir) * 127;
01178                 uDot = DotProduct(up, dir) * 127;
01179 
01180                 ucmd.forwardmove = floor(fDot);
01181                 ucmd.rightmove = floor(rDot);
01182                 ucmd.upmove = floor(uDot);
01183         }
01184         else
01185         {
01186                 //Cut velocity?
01187                 VectorClear( NPC->client->ps.velocity );
01188         }
01189 
01190         NPC_UpdateAngles( qtrue, qtrue );
01191 }

void NPC_BSRemote_Default void   ) 
 

Definition at line 375 of file NPC_AI_Remote.c.

References gentity_s::enemy, NPC, NPCInfo, Remote_Attack(), Remote_Idle(), Remote_Patrol(), SCF_LOOK_FOR_ENEMIES, and gNPC_t::scriptFlags.

Referenced by NPC_BehaviorSet_Remote().

00376 {
00377         if ( NPC->enemy )
00378         {
00379                 Remote_Attack();
00380         }
00381         else if ( NPCInfo->scriptFlags & SCF_LOOK_FOR_ENEMIES )
00382         {
00383                 Remote_Patrol();
00384         }
00385         else
00386         {
00387                 Remote_Idle();
00388         }
00389 }

void NPC_BSSeeker_Default void   ) 
 

Definition at line 523 of file NPC_AI_Seeker.c.

References Boba_FireDecide(), CLASS_BOBAFETT, CLASS_SEEKER, gentity_s::client, CON_DISCONNECTED, clientPersistant_t::connected, DAMAGE_NO_PROTECTION, gentity_s::enemy, ENTITYNUM_NONE, G_Damage(), g_entities, gentity_t, gentity_s::health, gentity_s::inuse, MOD_TELEFRAG, NPC, gclient_s::NPC_class, NULL, entityState_s::number, entityShared_t::ownerNum, gclient_s::pers, gentity_s::r, gentity_s::random, random, gentity_s::s, Seeker_Attack(), and Seeker_FollowOwner().

Referenced by NPC_BehaviorSet_Seeker().

00524 {
00525         /*
00526         if ( in_camera )
00527         {
00528                 if ( NPC->client->NPC_class != CLASS_BOBAFETT )
00529                 {
00530                         // cameras make me commit suicide....
00531                         G_Damage( NPC, NPC, NPC, NULL, NULL, 999, 0, MOD_UNKNOWN );
00532                 }
00533         }
00534         */
00535         //N/A for MP.
00536         if ( NPC->r.ownerNum < ENTITYNUM_NONE )
00537         {
00538                 gentity_t *owner = &g_entities[0];
00539                 if ( owner->health <= 0 
00540                         || (owner->client && owner->client->pers.connected == CON_DISCONNECTED) )
00541                 {//owner is dead or gone
00542                         //remove me
00543                         G_Damage( NPC, NULL, NULL, NULL, NULL, 10000, DAMAGE_NO_PROTECTION, MOD_TELEFRAG );
00544                         return;
00545                 }
00546         }
00547 
00548         if ( NPC->random == 0.0f )
00549         {
00550                 // used to offset seekers around a circle so they don't occupy the same spot.  This is not a fool-proof method.
00551                 NPC->random = random() * 6.3f; // roughly 2pi
00552         }
00553 
00554         if ( NPC->enemy && NPC->enemy->health && NPC->enemy->inuse )
00555         {
00556                 if ( NPC->client->NPC_class != CLASS_BOBAFETT && ( NPC->enemy->s.number == 0 || ( NPC->enemy->client && NPC->enemy->client->NPC_class == CLASS_SEEKER )) )
00557                 {
00558                         //hacked to never take the player as an enemy, even if the player shoots at it
00559                         NPC->enemy = NULL;
00560                 }
00561                 else
00562                 {
00563                         Seeker_Attack();
00564                         if ( NPC->client->NPC_class == CLASS_BOBAFETT )
00565                         {
00566                                 Boba_FireDecide();
00567                         }
00568                         return;
00569                 }
00570         }
00571 
00572         // In all other cases, follow the player and look for enemies to take on
00573         Seeker_FollowOwner();
00574 }

void NPC_BSSentry_Default void   ) 
 

Definition at line 557 of file NPC_AI_Sentry.c.

References gentity_s::enemy, gNPC_t::localState, LSTATE_WAKEUP, NPC, NPC_Sentry_Patrol(), NPCInfo, SCF_LOOK_FOR_ENEMIES, gNPC_t::scriptFlags, Sentry_AttackDecision(), Sentry_Idle(), sentry_use(), gentity_s::targetname, and gentity_s::use.

Referenced by NPC_BehaviorSet_Sentry().

00558 {
00559         if ( NPC->targetname )
00560         {
00561                 NPC->use = sentry_use;
00562         }
00563 
00564         if (( NPC->enemy ) && (NPCInfo->localState != LSTATE_WAKEUP))
00565         {
00566                 // Don't attack if waking up or if no enemy
00567                 Sentry_AttackDecision();
00568         }
00569         else if ( NPCInfo->scriptFlags & SCF_LOOK_FOR_ENEMIES )
00570         {
00571                 NPC_Sentry_Patrol();
00572         }
00573         else
00574         {
00575                 Sentry_Idle();
00576         }
00577 }

void NPC_BSWampa_Default void   ) 
 

Definition at line 506 of file NPC_AI_Wampa.c.

References BS_DEFAULT, BS_SEARCH, BS_WANDER, BUTTON_WALKING, usercmd_s::buttons, CHAN_AUTO, CHAN_VOICE, CLASS_WAMPA, gentity_s::client, gNPC_t::confusionTime, entityShared_t::currentOrigin, EF2_USE_ALT_ANIM, playerState_s::eFlags2, gentity_s::enemy, enemyDist, G_SetEnemy(), G_Sound(), G_SoundIndex(), gentity_t, gNPC_t::homeWp, gentity_s::inuse, gentity_s::lastEnemy, level, NPC, NPC_BSSearch(), NPC_BSSearchStart(), NPC_BSWander(), NPC_CheckEnemy(), NPC_CheckEnemyExt(), gclient_s::NPC_class, NPC_FaceEnemy(), NPC_UpdateAngles(), NPCInfo, NULL, gclient_s::ps, Q_irand(), qfalse, qtrue, gentity_s::r, gentity_s::s, SCF_LOOK_FOR_ENEMIES, gNPC_t::scriptFlags, gentity_s::spawnflags, gNPC_t::tempBehavior, level_locals_t::time, entityState_s::time, TIMER_Done(), TIMER_Remove(), TIMER_Set(), ucmd, va(), ValidEnemy(), Wampa_Attack(), Wampa_CheckRoar(), Wampa_Combat(), Wampa_Idle(), Wampa_Patrol(), gentity_s::waypoint, and WAYPOINT_NONE.

Referenced by NPC_RunBehavior().

00507 {
00508         NPC->client->ps.eFlags2 &= ~EF2_USE_ALT_ANIM;
00509         //NORMAL ANIMS
00510         //      stand1 = normal stand
00511         //      walk1 = normal, non-angry walk
00512         //      walk2 = injured
00513         //      run1 = far away run
00514         //      run2 = close run
00515         //VICTIM ANIMS
00516         //      grabswipe = melee1 - sweep out and grab
00517         //      stand2 attack = attack4 - while holding victim, swipe at him
00518         //      walk3_drag = walk5 - walk with drag
00519         //      stand2 = hold victim
00520         //      stand2to1 = drop victim
00521         if ( !TIMER_Done( NPC, "rageTime" ) )
00522         {//do nothing but roar first time we see an enemy
00523                 NPC_FaceEnemy( qtrue );
00524                 return;
00525         }
00526         if ( NPC->enemy )
00527         {
00528                 if ( !TIMER_Done(NPC,"attacking") )
00529                 {//in middle of attack
00530                         //face enemy
00531                         NPC_FaceEnemy( qtrue );
00532                         //continue attack logic
00533                         enemyDist = Distance( NPC->r.currentOrigin, NPC->enemy->r.currentOrigin );
00534                         Wampa_Attack( enemyDist, qfalse );
00535                         return;
00536                 }
00537                 else
00538                 {
00539                         if ( TIMER_Done(NPC,"angrynoise") )
00540                         {
00541                                 G_Sound( NPC, CHAN_VOICE, G_SoundIndex( va("sound/chars/wampa/misc/anger%d.wav", Q_irand(1, 2)) ) );
00542 
00543                                 TIMER_Set( NPC, "angrynoise", Q_irand( 5000, 10000 ) );
00544                         }
00545                         //else, if he's in our hand, we eat, else if he's on the ground, we keep attacking his dead body for a while
00546                         if( NPC->enemy->client && NPC->enemy->client->NPC_class == CLASS_WAMPA )
00547                         {//got mad at another Wampa, look for a valid enemy
00548                                 if ( TIMER_Done( NPC, "wampaInfight" ) )
00549                                 {
00550                                         NPC_CheckEnemyExt( qtrue );
00551                                 }
00552                         }
00553                         else
00554                         {
00555                                 if ( ValidEnemy( NPC->enemy ) == qfalse )
00556                                 {
00557                                         TIMER_Remove( NPC, "lookForNewEnemy" );//make them look again right now
00558                                         if ( !NPC->enemy->inuse || level.time - NPC->enemy->s.time > Q_irand( 10000, 15000 ) )
00559                                         {//it's been a while since the enemy died, or enemy is completely gone, get bored with him
00560                                                 NPC->enemy = NULL;
00561                                                 Wampa_Patrol();
00562                                                 NPC_UpdateAngles( qtrue, qtrue );
00563                                                 //just lost my enemy
00564                                                 if ( (NPC->spawnflags&2) )
00565                                                 {//search around me if I don't have an enemy
00566                                                         NPC_BSSearchStart( NPC->waypoint, BS_SEARCH );
00567                                                         NPCInfo->tempBehavior = BS_DEFAULT;
00568                                                 }
00569                                                 else if ( (NPC->spawnflags&1) )
00570                                                 {//wander if I don't have an enemy
00571                                                         NPC_BSSearchStart( NPC->waypoint, BS_WANDER );
00572                                                         NPCInfo->tempBehavior = BS_DEFAULT;
00573                                                 }
00574                                                 return;
00575                                         }
00576                                 }
00577                                 if ( TIMER_Done( NPC, "lookForNewEnemy" ) )
00578                                 {
00579                                         gentity_t *newEnemy, *sav_enemy = NPC->enemy;//FIXME: what about NPC->lastEnemy?
00580                                         NPC->enemy = NULL;
00581                                         newEnemy = NPC_CheckEnemy( NPCInfo->confusionTime < level.time, qfalse, qfalse );
00582                                         NPC->enemy = sav_enemy;
00583                                         if ( newEnemy && newEnemy != sav_enemy )
00584                                         {//picked up a new enemy!
00585                                                 NPC->lastEnemy = NPC->enemy;
00586                                                 G_SetEnemy( NPC, newEnemy );
00587                                                 //hold this one for at least 5-15 seconds
00588                                                 TIMER_Set( NPC, "lookForNewEnemy", Q_irand( 5000, 15000 ) );
00589                                         }
00590                                         else
00591                                         {//look again in 2-5 secs
00592                                                 TIMER_Set( NPC, "lookForNewEnemy", Q_irand( 2000, 5000 ) );
00593                                         }
00594                                 }
00595                         }
00596                         Wampa_Combat();
00597                         return;
00598                 }
00599         }
00600         else 
00601         {
00602                 if ( TIMER_Done(NPC,"idlenoise") )
00603                 {
00604                         G_Sound( NPC, CHAN_AUTO, G_SoundIndex( "sound/chars/wampa/misc/anger3.wav" ) );
00605 
00606                         TIMER_Set( NPC, "idlenoise", Q_irand( 2000, 4000 ) );
00607                 }
00608                 if ( (NPC->spawnflags&2) )
00609                 {//search around me if I don't have an enemy
00610                         if ( NPCInfo->homeWp == WAYPOINT_NONE )
00611                         {//no homewap, initialize the search behavior
00612                                 NPC_BSSearchStart( WAYPOINT_NONE, BS_SEARCH );
00613                                 NPCInfo->tempBehavior = BS_DEFAULT;
00614                         }
00615                         ucmd.buttons |= BUTTON_WALKING;
00616                         NPC_BSSearch();//this automatically looks for enemies
00617                 }
00618                 else if ( (NPC->spawnflags&1) )
00619                 {//wander if I don't have an enemy
00620                         if ( NPCInfo->homeWp == WAYPOINT_NONE )
00621                         {//no homewap, initialize the wander behavior
00622                                 NPC_BSSearchStart( WAYPOINT_NONE, BS_WANDER );
00623                                 NPCInfo->tempBehavior = BS_DEFAULT;
00624                         }
00625                         ucmd.buttons |= BUTTON_WALKING;
00626                         NPC_BSWander();
00627                         if ( NPCInfo->scriptFlags & SCF_LOOK_FOR_ENEMIES )
00628                         {
00629                                 if ( NPC_CheckEnemyExt( qtrue ) == qfalse )
00630                                 {
00631                                         Wampa_Idle();
00632                                 }
00633                                 else
00634                                 {
00635                                         Wampa_CheckRoar( NPC );
00636                                         TIMER_Set( NPC, "lookForNewEnemy", Q_irand( 5000, 15000 ) );
00637                                 }
00638                         }
00639                 }
00640                 else
00641                 {
00642                         if ( NPCInfo->scriptFlags & SCF_LOOK_FOR_ENEMIES )
00643                         {
00644                                 Wampa_Patrol();
00645                         }
00646                         else
00647                         {
00648                                 Wampa_Idle();
00649                         }
00650                 }
00651         }
00652 
00653         NPC_UpdateAngles( qtrue, qtrue );
00654 }

void NPC_CheckAllClear void   ) 
 

Definition at line 1113 of file NPC_reactions.c.

Referenced by NPC_ExecuteBState().

01114 {
01115         //FIXME: need to make this happen only once after losing enemies, not over and over again
01116         /*
01117         if ( NPC->client && !NPC->enemy && level.time - teamLastEnemyTime[NPC->client->playerTeam] > 10000 )
01118         {//Team hasn't seen an enemy in 10 seconds
01119                 if ( !Q_irand( 0, 2 ) )
01120                 {
01121                         G_AddVoiceEvent( NPC, Q_irand(EV_SETTLE1, EV_SETTLE3), 3000 );
01122                 }
01123         }
01124         */
01125 }

void NPC_CheckAttackHold void   ) 
 

Definition at line 851 of file NPC.c.

References gNPC_t::attackHold, gNPC_t::attackHoldTime, BUTTON_ATTACK, usercmd_s::buttons, entityShared_t::currentOrigin, gentity_s::enemy, level, NPC, NPC_MaxDistSquaredForWeapon(), NPCInfo, gentity_s::r, level_locals_t::time, ucmd, vec3_t, and VectorSubtract.

Referenced by NPC_ExecuteBState().

00852 {
00853         vec3_t          vec;
00854 
00855         // If they don't have an enemy they shouldn't hold their attack anim.
00856         if ( !NPC->enemy )
00857         {
00858                 NPCInfo->attackHoldTime = 0;
00859                 return;
00860         }
00861 
00862 /*      if ( ( NPC->client->ps.weapon == WP_BORG_ASSIMILATOR ) || ( NPC->client->ps.weapon == WP_BORG_DRILL ) )
00863         {//FIXME: don't keep holding this if can't hit enemy?
00864 
00865                 // If they don't have shields ( been disabled) they shouldn't hold their attack anim.
00866                 if ( !(NPC->NPC->aiFlags & NPCAI_SHIELDS) )
00867                 {
00868                         NPCInfo->attackHoldTime = 0;
00869                         return;
00870                 }
00871 
00872                 VectorSubtract(NPC->enemy->r.currentOrigin, NPC->r.currentOrigin, vec);
00873                 if( VectorLengthSquared(vec) > NPC_MaxDistSquaredForWeapon() )
00874                 {
00875                         NPCInfo->attackHoldTime = 0;
00876                         PM_SetTorsoAnimTimer(NPC, &NPC->client->ps.torsoAnimTimer, 0);
00877                 }
00878                 else if( NPCInfo->attackHoldTime && NPCInfo->attackHoldTime > level.time )
00879                 {
00880                         ucmd.buttons |= BUTTON_ATTACK;
00881                 }
00882                 else if ( ( NPCInfo->attackHold ) && ( ucmd.buttons & BUTTON_ATTACK ) )
00883                 {
00884                         NPCInfo->attackHoldTime = level.time + NPCInfo->attackHold;
00885                         PM_SetTorsoAnimTimer(NPC, &NPC->client->ps.torsoAnimTimer, NPCInfo->attackHold);
00886                 }
00887                 else
00888                 {
00889                         NPCInfo->attackHoldTime = 0;
00890                         PM_SetTorsoAnimTimer(NPC, &NPC->client->ps.torsoAnimTimer, 0);
00891                 }
00892         }
00893         else*/
00894         {//everyone else...?  FIXME: need to tie this into AI somehow?
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 }

void NPC_CheckAttackScript void   ) 
 

Definition at line 840 of file NPC.c.

References BSET_ATTACK, BUTTON_ATTACK, usercmd_s::buttons, G_ActivateBehavior(), NPC, and ucmd.

Referenced by NPC_ExecuteBState().

00841 {
00842         if(!(ucmd.buttons & BUTTON_ATTACK))
00843         {
00844                 return;
00845         }
00846 
00847         G_ActivateBehavior(NPC, BSET_ATTACK);
00848 }

void NPC_CheckCharmed void   ) 
 

Definition at line 1687 of file NPC_utils.c.

References BS_DEFAULT, BS_FOLLOW_LEADER, gNPC_t::charmedTime, gentity_s::client, gclient_s::enemyTeam, EV_CONFUSE1, EV_CONFUSE3, G_AddVoiceEvent(), G_ClearEnemy(), gentity_s::genericValue1, gentity_s::genericValue2, gentity_s::genericValue3, gclient_s::leader, level, NPC, NPCInfo, NULL, gclient_s::playerTeam, Q_irand(), gentity_s::s, entityState_s::teamowner, gNPC_t::tempBehavior, and level_locals_t::time.

Referenced by NPC_RunBehavior().

01688 {
01689         if ( NPCInfo->charmedTime && NPCInfo->charmedTime < level.time && NPC->client )
01690         {//we were charmed, set us back!
01691                 NPC->client->playerTeam = NPC->genericValue1;
01692                 NPC->client->enemyTeam = NPC->genericValue2;
01693                 NPC->s.teamowner = NPC->genericValue3;
01694 
01695                 NPC->client->leader = NULL;
01696                 if ( NPCInfo->tempBehavior == BS_FOLLOW_LEADER )
01697                 {
01698                         NPCInfo->tempBehavior = BS_DEFAULT;
01699                 }
01700                 G_ClearEnemy( NPC );
01701                 NPCInfo->charmedTime = 0;
01702                 //say something to let player know you've snapped out of it
01703                 G_AddVoiceEvent( NPC, Q_irand(EV_CONFUSE1, EV_CONFUSE3), 2000 );
01704         }
01705 }

void NPC_CheckInSolid void   ) 
 

Definition at line 1764 of file NPC.c.

References trace_t::allsolid, gentity_s::clipmask, entityShared_t::currentOrigin, G_SetOrigin(), gNPC_t::lastClearOrigin, entityShared_t::maxs, entityShared_t::mins, NPC, NPCInfo, entityState_s::number, gentity_s::r, gentity_s::s, trace_t::startsolid, trap_LinkEntity(), trap_Trace(), vec3_t, and VectorCopy.

01765 {
01766         trace_t trace;
01767         vec3_t  point;
01768         VectorCopy(NPC->r.currentOrigin, point);
01769         point[2] -= 0.25;
01770 
01771         trap_Trace(&trace, NPC->r.currentOrigin, NPC->r.mins, NPC->r.maxs, point, NPC->s.number, NPC->clipmask);
01772         if(!trace.startsolid && !trace.allsolid)
01773         {
01774                 VectorCopy(NPC->r.currentOrigin, NPCInfo->lastClearOrigin);
01775         }
01776         else
01777         {
01778                 if(VectorLengthSquared(NPCInfo->lastClearOrigin))
01779                 {
01780 //                      Com_Printf("%s stuck in solid at %s: fixing...\n", NPC->script_targetname, vtos(NPC->r.currentOrigin));
01781                         G_SetOrigin(NPC, NPCInfo->lastClearOrigin);
01782                         trap_LinkEntity(NPC);
01783                 }
01784         }
01785 }

qboolean NPC_CheckLookTarget gentity_t self  ) 
 

Definition at line 1653 of file NPC_utils.c.

01654 {
01655         if ( self->client )
01656         {
01657                 if ( self->client->renderInfo.lookTarget >= 0 && self->client->renderInfo.lookTarget < ENTITYNUM_WORLD )
01658                 {//within valid range
01659                         if ( (&g_entities[self->client->renderInfo.lookTarget] == NULL) || !g_entities[self->client->renderInfo.lookTarget].inuse )
01660                         {//lookTarget not inuse or not valid anymore
01661                                 NPC_ClearLookTarget( self );
01662                         }
01663                         else if ( self->client->renderInfo.lookTargetClearTime && self->client->renderInfo.lookTargetClearTime < level.time )
01664                         {//Time to clear lookTarget
01665                                 NPC_ClearLookTarget( self );
01666                         }
01667                         else if ( g_entities[self->client->renderInfo.lookTarget].client && self->enemy && (&g_entities[self->client->renderInfo.lookTarget] != self->enemy) )
01668                         {//should always look at current enemy if engaged in battle... FIXME: this could override certain scripted lookTargets...???
01669                                 NPC_ClearLookTarget( self );
01670                         }
01671                         else
01672                         {
01673                                 return qtrue;
01674                         }
01675                 }
01676         }
01677 
01678         return qfalse;
01679 }

void NPC_CheckPlayerAim void   ) 
 

Definition at line 1095 of file NPC_reactions.c.

Referenced by NPC_ExecuteBState().

01096 {
01097         //FIXME: need appropriate dialogue
01098         /*
01099         gentity_t *player = &g_entities[0];
01100 
01101         if ( player && player->client && player->client->ps.weapon > (int)(WP_NONE) && player->client->ps.weapon < (int)(WP_TRICORDER) )
01102         {//player has a weapon ready
01103                 if ( g_crosshairEntNum == NPC->s.number && level.time - g_crosshairEntTime < 200 
01104                         && g_crosshairSameEntTime >= 3000 && g_crosshairEntDist < 256 )
01105                 {//if the player holds the crosshair on you for a few seconds
01106                         //ask them what the fuck they're doing
01107                         G_AddVoiceEvent( NPC, Q_irand( EV_FF_1A, EV_FF_1C ), 0 );
01108                 }
01109         }
01110         */
01111 }

qboolean NPC_CheckSurrender void   ) 
 

Definition at line 1341 of file NPC_behavior.c.

References gentity_s::client, entityShared_t::currentOrigin, gentity_s::enemy, ENTITYNUM_NONE, playerState_s::fd, forcedata_s::forcePowerDebounce, FP_SABER_DEFENSE, playerState_s::groundEntityNum, gentity_s::health, InFOV(), level, NPC, NPC_SomeoneLookingAtMe(), gentity_s::painDebounceTime, PM_InKnockDown(), gclient_s::ps, qboolean, qfalse, gentity_s::r, gentity_s::s, TID_MOVE_NAV, level_locals_t::time, trap_ICARUS_TaskIDPending(), trap_InPVS(), entityState_s::weapon, playerState_s::weaponTime, WP_FLECHETTE, WP_NONE, WP_REPEATER, WP_ROCKET_LAUNCHER, WP_SABER, and WP_STUN_BATON.

Referenced by NPC_BSFlee(), and NPC_RunBehavior().

01342 {
01343         if ( !trap_ICARUS_TaskIDPending( NPC, TID_MOVE_NAV ) 
01344                 && NPC->client->ps.groundEntityNum != ENTITYNUM_NONE 
01345                 && !NPC->client->ps.weaponTime && !PM_InKnockDown( &NPC->client->ps )
01346                 && NPC->enemy && NPC->enemy->client && NPC->enemy->enemy == NPC && NPC->enemy->s.weapon != WP_NONE && NPC->enemy->s.weapon != WP_STUN_BATON 
01347                 && NPC->enemy->health > 20 && NPC->enemy->painDebounceTime < level.time - 3000 && NPC->enemy->client->ps.fd.forcePowerDebounce[FP_SABER_DEFENSE] < level.time - 1000 )
01348         {//don't surrender if scripted to run somewhere or if we're in the air or if we're busy or if we don't have an enemy or if the enemy is not mad at me or is hurt or not a threat or busy being attacked
01349                 //FIXME: even if not in a group, don't surrender if there are other enemies in the PVS and within a certain range?
01350                 if ( NPC->s.weapon != WP_ROCKET_LAUNCHER 
01351                         && NPC->s.weapon != WP_REPEATER
01352                         && NPC->s.weapon != WP_FLECHETTE
01353                         && NPC->s.weapon != WP_SABER )
01354                 {//jedi and heavy weapons guys never surrender
01355                         //FIXME: rework all this logic into some orderly fashion!!!
01356                         if ( NPC->s.weapon != WP_NONE )
01357                         {//they have a weapon so they'd have to drop it to surrender
01358                                 //don't give up unless low on health
01359                                 if ( NPC->health > 25 /*|| NPC->health >= NPC->max_health*/ )
01360                                 { //rwwFIXMEFIXME: Keep max health not a ps state?
01361                                         return qfalse;
01362                                 }
01363                                 //if ( g_crosshairEntNum == NPC->s.number && NPC->painDebounceTime > level.time )
01364                                 if (NPC_SomeoneLookingAtMe(NPC) && NPC->painDebounceTime > level.time)
01365                                 {//if he just shot me, always give up
01366                                         //fall through
01367                                 }
01368                                 else
01369                                 {//don't give up unless facing enemy and he's very close
01370                                         if ( !InFOV( NPC->enemy, NPC, 60, 30 ) )
01371                                         {//I'm not looking at them
01372                                                 return qfalse;
01373                                         }
01374                                         else if ( DistanceSquared( NPC->r.currentOrigin, NPC->enemy->r.currentOrigin ) < 65536/*256*256*/ )
01375                                         {//they're not close
01376                                                 return qfalse;
01377                                         }
01378                                         else if ( !trap_InPVS( NPC->r.currentOrigin, NPC->enemy->r.currentOrigin ) )
01379                                         {//they're not in the same room
01380                                                 return qfalse;
01381                                         }
01382                                 }
01383                         }
01384                         //fixme: this logic keeps making npc's randomly surrender
01385                         /*
01386                         if ( NPCInfo->group && NPCInfo->group->numGroup <= 1 )
01387                         {//I'm alone but I was in a group//FIXME: surrender anyway if just melee or no weap?
01388                                 if ( NPC->s.weapon == WP_NONE 
01389                                         //NPC has a weapon
01390                                         || (NPC->enemy && NPC->enemy->s.number < MAX_CLIENTS)
01391                                         || (NPC->enemy->s.weapon == WP_SABER&&NPC->enemy->client&&!NPC->enemy->client->ps.saberHolstered)
01392                                         || (NPC->enemy->NPC && NPC->enemy->NPC->group && NPC->enemy->NPC->group->numGroup > 2) )
01393                                 {//surrender only if have no weapon or fighting a player or jedi or if we are outnumbered at least 3 to 1
01394                                         if ( (NPC->enemy && NPC->enemy->s.number < MAX_CLIENTS) )
01395                                         {//player is the guy I'm running from
01396                                                 //if ( g_crosshairEntNum == NPC->s.number )
01397                                                 if (NPC_SomeoneLookingAtMe(NPC))
01398                                                 {//give up if player is aiming at me
01399                                                         NPC_Surrender();
01400                                                         NPC_UpdateAngles( qtrue, qtrue );
01401                                                         return qtrue;
01402                                                 }
01403                                                 else if ( NPC->enemy->s.weapon == WP_SABER )
01404                                                 {//player is using saber
01405                                                         if ( InFOV( NPC, NPC->enemy, 60, 30 ) )
01406                                                         {//they're looking at me
01407                                                                 if ( DistanceSquared( NPC->r.currentOrigin, NPC->enemy->r.currentOrigin ) < 16384 )
01408                                                                 {//they're close
01409                                                                         if ( trap_InPVS( NPC->r.currentOrigin, NPC->enemy->r.currentOrigin ) )
01410                                                                         {//they're in the same room
01411                                                                                 NPC_Surrender();
01412                                                                                 NPC_UpdateAngles( qtrue, qtrue );
01413                                                                                 return qtrue;
01414                                                                         }
01415                                                                 }
01416                                                         }
01417                                                 }
01418                                         }
01419                                         else if ( NPC->enemy )
01420                                         {//???
01421                                                 //should NPC's surrender to others?
01422                                                 if ( InFOV( NPC, NPC->enemy, 30, 30 ) )
01423                                                 {//they're looking at me
01424                                                         if ( DistanceSquared( NPC->r.currentOrigin, NPC->enemy->r.currentOrigin ) < 4096 )
01425                                                         {//they're close
01426                                                                 if ( trap_InPVS( NPC->r.currentOrigin, NPC->enemy->r.currentOrigin ) )
01427                                                                 {//they're in the same room
01428                                                                         //FIXME: should player-team NPCs not fire on surrendered NPCs?
01429                                                                         NPC_Surrender();
01430                                                                         NPC_UpdateAngles( qtrue, qtrue );
01431                                                                         return qtrue;
01432                                                                 }
01433                                                         }
01434                                                 }
01435                                         }
01436                                 }
01437                         }
01438                         */
01439                 }
01440         }
01441         return qfalse;
01442 }

void NPC_ExecuteBState gentity_t self  ) 
 

Definition at line 1576 of file NPC.c.

References gentity_s::attackDebounceTime, gNPC_t::attackHoldTime, gNPC_t::behaviorState, BSET_DELAYED, bState_t, BUTTON_ALT_ATTACK, BUTTON_ATTACK, usercmd_s::buttons, client, gentity_s::client, ClientThink(), gNPC_t::combatMove, gNPC_t::defaultBehavior, gentity_s::delayScriptTime, gentity_s::enemy, ENTITYNUM_NONE, FL_DONT_SHOOT, gentity_s::flags, G_ActivateBehavior(), G_ClearEnemy(), gentity_t, gentity_s::inuse, gNPC_t::last_ucmd, level, memcpy(), gentity_s::next_roff_time, gentity_s::NPC, NPC, NPC_ApplyRoff(), NPC_ApplyScriptFlags(), NPC_AvoidWallsAndCliffs(), NPC_CheckAllClear(), NPC_CheckAttackHold(), NPC_CheckAttackScript(), NPC_CheckLookTarget(), NPC_CheckPlayerAim(), NPC_HandleAIFlags(), NPC_KeepCurrentFacing(), NPC_RunBehavior(), NPC_SetAnim(), NPC_SetLookTarget(), NPCInfo, NPCTEAM_ENEMY, NULL, entityState_s::number, gclient_s::playerTeam, gclient_s::ps, qfalse, gentity_s::s, playerState_s::saberLockEnemy, playerState_s::saberLockTime, SCF_FORCED_MARCH, gNPC_t::scriptFlags, usercmd_s::serverTime, SETANIM_FLAG_NORMAL, SETANIM_TORSO, gNPC_t::surrenderTime, gNPC_t::tempBehavior, level_locals_t::time, TORSO_WEAPONIDLE3, TORSO_WEAPONREADY1, TORSO_WEAPONREADY3, entityState_s::torsoAnim, gNPC_t::touchedByPlayer, ucmd, usercmd_t, playerState_s::weapon, WEAPON_IDLE, WEAPON_READY, playerState_s::weaponstate, WP_BRYAR_PISTOL, and WP_SABER.

Referenced by NPC_Think().

01577 {
01578         bState_t        bState;
01579 
01580         NPC_HandleAIFlags();
01581 
01582         //FIXME: these next three bits could be a function call, some sort of setup/cleanup func
01583         //Lookmode must be reset every think cycle
01584         if(NPC->delayScriptTime && NPC->delayScriptTime <= level.time)
01585         {
01586                 G_ActivateBehavior( NPC, BSET_DELAYED);
01587                 NPC->delayScriptTime = 0;
01588         }
01589 
01590         //Clear this and let bState set it itself, so it automatically handles changing bStates... but we need a set bState wrapper func
01591         NPCInfo->combatMove = qfalse;
01592 
01593         //Execute our bState
01594         if(NPCInfo->tempBehavior)
01595         {//Overrides normal behavior until cleared
01596                 bState = NPCInfo->tempBehavior;
01597         }
01598         else
01599         {
01600                 if(!NPCInfo->behaviorState)
01601                         NPCInfo->behaviorState = NPCInfo->defaultBehavior;
01602 
01603                 bState = NPCInfo->behaviorState;
01604         }
01605 
01606         //Pick the proper bstate for us and run it
01607         NPC_RunBehavior( self->client->playerTeam, bState );
01608         
01609 
01610 //      if(bState != BS_POINT_COMBAT && NPCInfo->combatPoint != -1)
01611 //      {
01612                 //level.combatPoints[NPCInfo->combatPoint].occupied = qfalse;
01613                 //NPCInfo->combatPoint = -1;
01614 //      }
01615 
01616         //Here we need to see what the scripted stuff told us to do
01617 //Only process snapshot if independant and in combat mode- this would pick enemies and go after needed items
01618 //      ProcessSnapshot();
01619 
01620 //Ignore my needs if I'm under script control- this would set needs for items
01621 //      CheckSelf();
01622 
01623         //Back to normal?  All decisions made?
01624         
01625         //FIXME: don't walk off ledges unless we can get to our goal faster that way, or that's our goal's surface
01626         //NPCPredict();
01627 
01628         if ( NPC->enemy )
01629         {
01630                 if ( !NPC->enemy->inuse )
01631                 {//just in case bState doesn't catch this
01632                         G_ClearEnemy( NPC );
01633                 }
01634         }
01635 
01636         if ( NPC->client->ps.saberLockTime && NPC->client->ps.saberLockEnemy != ENTITYNUM_NONE )
01637         {
01638                 NPC_SetLookTarget( NPC, NPC->client->ps.saberLockEnemy, level.time+1000 );
01639         }
01640         else if ( !NPC_CheckLookTarget( NPC ) )
01641         {
01642                 if ( NPC->enemy )
01643                 {
01644                         NPC_SetLookTarget( NPC, NPC->enemy->s.number, 0 );
01645                 }
01646         }
01647 
01648         if ( NPC->enemy )
01649         {
01650                 if(NPC->enemy->flags & FL_DONT_SHOOT)
01651                 {
01652                         ucmd.buttons &= ~BUTTON_ATTACK;
01653                         ucmd.buttons &= ~BUTTON_ALT_ATTACK;
01654                 }
01655                 else if ( NPC->client->playerTeam != NPCTEAM_ENEMY && NPC->enemy->NPC && (NPC->enemy->NPC->surrenderTime > level.time || (NPC->enemy->NPC->scriptFlags&SCF_FORCED_MARCH)) )
01656                 {//don't shoot someone who's surrendering if you're a good guy
01657                         ucmd.buttons &= ~BUTTON_ATTACK;
01658                         ucmd.buttons &= ~BUTTON_ALT_ATTACK;
01659                 }
01660 
01661                 if(client->ps.weaponstate == WEAPON_IDLE)
01662                 {
01663                         client->ps.weaponstate = WEAPON_READY;
01664                 }
01665         }
01666         else 
01667         {
01668                 if(client->ps.weaponstate == WEAPON_READY)
01669                 {
01670                         client->ps.weaponstate = WEAPON_IDLE;
01671                 }
01672         }
01673 
01674         if(!(ucmd.buttons & BUTTON_ATTACK) && NPC->attackDebounceTime > level.time)
01675         {//We just shot but aren't still shooting, so hold the gun up for a while
01676                 if(client->ps.weapon == WP_SABER )
01677                 {//One-handed
01678                         NPC_SetAnim(NPC,SETANIM_TORSO,TORSO_WEAPONREADY1,SETANIM_FLAG_NORMAL);
01679                 }
01680                 else if(client->ps.weapon == WP_BRYAR_PISTOL)
01681                 {//Sniper pose
01682                         NPC_SetAnim(NPC,SETANIM_TORSO,TORSO_WEAPONREADY3,SETANIM_FLAG_NORMAL);
01683                 }
01684                 /*//FIXME: What's the proper solution here?
01685                 else
01686                 {//heavy weapon
01687                         NPC_SetAnim(NPC,SETANIM_TORSO,TORSO_WEAPONREADY3,SETANIM_FLAG_NORMAL);
01688                 }
01689                 */
01690         }
01691         else if ( !NPC->enemy )//HACK!
01692         {
01693 //              if(client->ps.weapon != WP_TRICORDER)
01694                 {
01695                         if( NPC->s.torsoAnim == TORSO_WEAPONREADY1 || NPC->s.torsoAnim == TORSO_WEAPONREADY3 )
01696                         {//we look ready for action, using one of the first 2 weapon, let's rest our weapon on our shoulder
01697                                 NPC_SetAnim(NPC,SETANIM_TORSO,TORSO_WEAPONIDLE3,SETANIM_FLAG_NORMAL);
01698                         }
01699                 }
01700         }
01701 
01702         NPC_CheckAttackHold();
01703         NPC_ApplyScriptFlags();
01704         
01705         //cliff and wall avoidance
01706         NPC_AvoidWallsAndCliffs();
01707 
01708         // run the bot through the server like it was a real client
01709 //=== Save the ucmd for the second no-think Pmove ============================
01710         ucmd.serverTime = level.time - 50;
01711         memcpy( &NPCInfo->last_ucmd, &ucmd, sizeof( usercmd_t ) );
01712         if ( !NPCInfo->attackHoldTime )
01713         {
01714                 NPCInfo->last_ucmd.buttons &= ~(BUTTON_ATTACK|BUTTON_ALT_ATTACK);//so we don't fire twice in one think
01715         }
01716 //============================================================================
01717         NPC_CheckAttackScript();
01718         NPC_KeepCurrentFacing();
01719 
01720         if ( !NPC->next_roff_time || NPC->next_roff_time < level.time )
01721         {//If we were following a roff, we don't do normal pmoves.
01722                 ClientThink( NPC->s.number, &ucmd );
01723         }
01724         else
01725         {
01726                 NPC_ApplyRoff();
01727         }
01728 
01729         // end of thinking cleanup
01730         NPCInfo->touchedByPlayer = NULL;
01731 
01732         NPC_CheckPlayerAim();
01733         NPC_CheckAllClear();
01734         
01735         /*if( ucmd.forwardmove || ucmd.rightmove )
01736         {
01737                 int     i, la = -1, ta = -1;
01738 
01739                 for(i = 0; i < MAX_ANIMATIONS; i++)
01740                 {
01741                         if( NPC->client->ps.legsAnim == i )
01742                         {
01743                                 la = i;
01744                         }
01745 
01746                         if( NPC->client->ps.torsoAnim == i )
01747                         {
01748                                 ta = i;
01749                         }
01750                         
01751                         if(la != -1 && ta != -1)
01752                         {
01753                                 break;
01754                         }
01755                 }
01756 
01757                 if(la != -1 && ta != -1)
01758                 {//FIXME: should never play same frame twice or restart an anim before finishing it
01759                         Com_Printf("LegsAnim: %s(%d) TorsoAnim: %s(%d)\n", animTable[la].name, NPC->renderInfo.legsFrame, animTable[ta].name, NPC->client->renderInfo.torsoFrame);
01760                 }
01761         }*/
01762 }

void NPC_HandleAIFlags void   ) 
 

Definition at line 738 of file NPC.c.

References gNPC_t::aiFlags, gNPC_t::consecutiveBlockedMoves, d_patched, gentity_s::enemy, EV_VICTORY1, EV_VICTORY3, gNPC_t::ffireCount, gNPC_t::ffireFadeDebounce, G_AddVoiceEvent(), gNPC_t::goalEntity, gNPC_t::greetingDebounceTime, vmCvar_t::integer, level, NPC, NPC_LostEnemyDecideChase(), NPCAI_LOST, NPCInfo, Q_irand(), and level_locals_t::time.

Referenced by NPC_ExecuteBState().

00739 {
00740         //FIXME: make these flags checks a function call like NPC_CheckAIFlagsAndTimers
00741         if ( NPCInfo->aiFlags & NPCAI_LOST )
00742         {//Print that you need help!
00743                 //FIXME: shouldn't remove this just yet if cg_draw needs it
00744                 NPCInfo->aiFlags &= ~NPCAI_LOST;
00745                 
00746                 /*
00747                 if ( showWaypoints )
00748                 {
00749                         Q3_DebugPrint(WL_WARNING, "%s can't navigate to target %s (my wp: %d, goal wp: %d)\n", NPC->targetname, NPCInfo->goalEntity->targetname, NPC->waypoint, NPCInfo->goalEntity->waypoint );
00750                 }
00751                 */
00752 
00753                 if ( NPCInfo->goalEntity && NPCInfo->goalEntity == NPC->enemy )
00754                 {//We can't nav to our enemy
00755                         //Drop enemy and see if we should search for him
00756                         NPC_LostEnemyDecideChase();
00757                 }
00758         }
00759 
00760         //MRJ Request:
00761         /*
00762         if ( NPCInfo->aiFlags & NPCAI_GREET_ALLIES && !NPC->enemy )//what if "enemy" is the greetEnt?
00763         {//If no enemy, look for teammates to greet
00764                 //FIXME: don't say hi to the same guy over and over again.
00765                 if ( NPCInfo->greetingDebounceTime < level.time )
00766                 {//Has been at least 2 seconds since we greeted last
00767                         if ( !NPCInfo->greetEnt )
00768                         {//Find a teammate whom I'm facing and who is facing me and within 128
00769                                 NPCInfo->greetEnt = NPC_PickAlly( qtrue, 128, qtrue, qtrue );
00770                         }
00771 
00772                         if ( NPCInfo->greetEnt && !Q_irand(0, 5) )
00773                         {//Start greeting someone
00774                                 qboolean        greeted = qfalse;
00775 
00776                                 //TODO:  If have a greetscript, run that instead?
00777 
00778                                 //FIXME: make them greet back?
00779                                 if( !Q_irand( 0, 2 ) )
00780                                 {//Play gesture anim (press gesture button?)
00781                                         greeted = qtrue;
00782                                         NPC_SetAnim( NPC, SETANIM_TORSO, Q_irand( BOTH_GESTURE1, BOTH_GESTURE3 ), SETANIM_FLAG_NORMAL|SETANIM_FLAG_HOLD );
00783                                         //NOTE: play full-body gesture if not moving?
00784                                 }
00785 
00786                                 if( !Q_irand( 0, 2 ) )
00787                                 {//Play random voice greeting sound
00788                                         greeted = qtrue;
00789                                         //FIXME: need NPC sound sets
00790 
00791                                         //G_AddVoiceEvent( NPC, Q_irand(EV_GREET1, EV_GREET3), 2000 );
00792                                 }
00793 
00794                                 if( !Q_irand( 0, 1 ) )
00795                                 {//set looktarget to them for a second or two
00796                                         greeted = qtrue;
00797                                         NPC_TempLookTarget( NPC, NPCInfo->greetEnt->s.number, 1000, 3000 );
00798                                 }
00799 
00800                                 if ( greeted )
00801                                 {//Did at least one of the things above
00802                                         //Don't greet again for 2 - 4 seconds
00803                                         NPCInfo->greetingDebounceTime = level.time + Q_irand( 2000, 4000 );
00804                                         NPCInfo->greetEnt = NULL;
00805                                 }
00806                         }
00807                 }
00808         }
00809         */
00810         //been told to play a victory sound after a delay
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                         //Com_Printf( "drop: %d < %d\n", NPCInfo->ffireCount, 3+((2-g_spskill.integer)*2) );
00823                         NPCInfo->ffireFadeDebounce = level.time + 3000;
00824                 }
00825         }
00826         if ( d_patched.integer )
00827         {//use patch-style navigation
00828                 if ( NPCInfo->consecutiveBlockedMoves > 20 )
00829                 {//been stuck for a while, try again?
00830                         NPCInfo->consecutiveBlockedMoves = 0;
00831                 }
00832         }
00833 }

void NPC_InitAI void   ) 
 

Definition at line 1981 of file NPC.c.

Referenced by NPC_InitGame().

01982 {
01983         /*
01984         trap_Cvar_Register(&g_saberRealisticCombat, "g_saberRealisticCombat", "0", CVAR_CHEAT);
01985 
01986         trap_Cvar_Register(&debugNoRoam, "d_noroam", "0", CVAR_CHEAT);
01987         trap_Cvar_Register(&debugNPCAimingBeam, "d_npcaiming", "0", CVAR_CHEAT);
01988         trap_Cvar_Register(&debugBreak, "d_break", "0", CVAR_CHEAT);
01989         trap_Cvar_Register(&debugNPCAI, "d_npcai", "0", CVAR_CHEAT);
01990         trap_Cvar_Register(&debugNPCFreeze, "d_npcfreeze", "0", CVAR_CHEAT);
01991         trap_Cvar_Register(&d_JediAI, "d_JediAI", "0", CVAR_CHEAT);
01992         trap_Cvar_Register(&d_noGroupAI, "d_noGroupAI", "0", CVAR_CHEAT);
01993         trap_Cvar_Register(&d_asynchronousGroupAI, "d_asynchronousGroupAI", "0", CVAR_CHEAT);
01994         
01995         //0 = never (BORING)
01996         //1 = kyle only
01997         //2 = kyle and last enemy jedi
01998         //3 = kyle and any enemy jedi
01999         //4 = kyle and last enemy in a group
02000         //5 = kyle and any enemy
02001         //6 = also when kyle takes pain or enemy jedi dodges player saber swing or does an acrobatic evasion
02002 
02003         trap_Cvar_Register(&d_slowmodeath, "d_slowmodeath", "0", CVAR_CHEAT);
02004 
02005         trap_Cvar_Register(&d_saberCombat, "d_saberCombat", "0", CVAR_CHEAT);
02006 
02007         trap_Cvar_Register(&g_spskill, "g_npcspskill", "0", CVAR_ARCHIVE | CVAR_USERINFO);
02008         */
02009 }

void NPC_InitGame void   ) 
 

Definition at line 2041 of file NPC.c.

References NPC_InitAI(), and NPC_LoadParms().

Referenced by G_InitGame().

02042 {
02043 //      globals.NPCs = (gNPC_t *) gi.TagMalloc(game.maxclients * sizeof(game.bots[0]), TAG_GAME);
02044 //      trap_Cvar_Register(&debugNPCName, "d_npc", "0", CVAR_CHEAT);
02045 
02046         NPC_LoadParms();
02047         NPC_InitAI();
02048 //      NPC_InitAnimTable();
02049         /*
02050         ResetTeamCounters();
02051         for ( int team = NPCTEAM_FREE; team < NPCTEAM_NUM_TEAMS; team++ )
02052         {
02053                 teamLastEnemyTime[team] = -10000;
02054         }
02055         */
02056 }

void NPC_KeepCurrentFacing void   ) 
 

Definition at line 920 of file NPC.c.

References ANGLE2SHORT, usercmd_s::angles, client, playerState_s::delta_angles, PITCH, gclient_s::ps, ucmd, playerState_s::viewangles, and YAW.

Referenced by NPC_ExecuteBState().

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 }

float NPC_MaxDistSquaredForWeapon void   ) 
 

Definition at line 1334 of file NPC_combat.c.

References saberInfo_t::blade, gentity_s::client, bladeInfo_t::lengthMax, entityShared_t::maxs, NPC, NPCInfo, gentity_s::r, gentity_s::s, gclient_s::saber, SCF_ALT_FIRE, gNPC_t::scriptFlags, gNPCstats_e::shootDistance, gNPC_t::stats, entityState_s::weapon, WP_BLASTER, WP_BRYAR_PISTOL, WP_DISRUPTOR, and WP_SABER.

01335 {
01336         if(NPCInfo->stats.shootDistance > 0)
01337         {//overrides default weapon dist
01338                 return NPCInfo->stats.shootDistance * NPCInfo->stats.shootDistance;
01339         }
01340 
01341         switch ( NPC->s.weapon ) 
01342         {
01343         case WP_BLASTER://scav rifle
01344                 return 1024 * 1024;//should be shorter?
01345                 break;
01346 
01347         case WP_BRYAR_PISTOL://prifle
01348                 return 1024 * 1024;
01349                 break;
01350 
01351                 /*
01352         case WP_BLASTER_PISTOL://prifle
01353                 return 1024 * 1024;
01354                 break;
01355                 */
01356 
01357         case WP_DISRUPTOR://disruptor
01358                 if ( NPCInfo->scriptFlags & SCF_ALT_FIRE )
01359                 {
01360                         return ( 4096 * 4096 );
01361                 }
01362                 else
01363                 {
01364                         return 1024 * 1024;
01365                 }
01366                 break;
01367 /*
01368         case WP_SABER:
01369                 return 1024 * 1024;
01370                 break;
01371         
01372 
01373         case WP_TRICORDER:
01374                 return 0;//tricorder
01375                 break;
01376 */
01377         case WP_SABER:
01378                 if ( NPC->client && NPC->client->saber[0].blade[0].lengthMax )
01379                 {//FIXME: account for whether enemy and I are heading towards each other!
01380                         return (NPC->client->saber[0].blade[0].lengthMax + NPC->r.maxs[0]*1.5)*(NPC->client->saber[0].blade[0].lengthMax + NPC->r.maxs[0]*1.5);
01381                 }
01382                 else
01383                 {
01384                         return 48*48;
01385                 }
01386                 break;
01387 
01388         default:
01389                 return 1024 * 1024;//was 0
01390                 break;
01391         }
01392 }

void NPC_RemoveBody gentity_t self  ) 
 

if ( self->client->playerTeam == NPCTEAM_SCAVENGERS || self->client->playerTeam == NPCTEAM_KLINGON

Definition at line 115 of file NPC.c.

References gentity_s::activator, CLASS_GALAKMECH, CLASS_INTERROGATOR, CLASS_MARK1, CLASS_MARK2, CLASS_PROBE, CLASS_PROTOCOL, CLASS_REMOTE, CLASS_SENTRY, gentity_s::client, CorpsePhysics(), entityShared_t::currentOrigin, EF2_HELD_BY_MONSTER, playerState_s::eFlags2, gentity_s::enemy, ENTITYNUM_WORLD, renderInfo_s::eyePoint, FRAMETIME, g_entities, G_FreeEntity(), gentity_t, level, Mark1_dying(), entityShared_t::maxs, gentity_s::message, gNPC_t::nextBStateThink, gentity_s::nextthink, gentity_s::NPC, gclient_s::NPC_class, NPCTEAM_ENEMY, entityState_s::number, gclient_s::playerTeam, gclient_s::ps, gentity_s::r, gclient_s::renderInfo, gentity_s::s, playerState_s::saberEntityNum, level_locals_t::time, gNPC_t::timeOfDeath, trap_ICARUS_IsRunning(), and trap_ICARUS_MaintainTaskManager().

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         {//I still have a key
00129                 return;
00130         }
00131 
00132         // I don't consider this a hack, it's creative coding . . . 
00133         // I agree, very creative... need something like this for ATST and GALAKMECH too!
00134         if (self->client->NPC_class == CLASS_MARK1)
00135         {
00136                 Mark1_dying( self );
00137         }
00138 
00139         // Since these blow up, remove the bounding box.
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                 //if ( !self->taskManager || !self->taskManager->IsRunning() )
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                         {//not being held by a Rancor
00152                                 G_FreeEntity( self );
00153                         }
00154                 }
00155                 return;
00156         }
00157 
00158         //FIXME: don't ever inflate back up?
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         {//never disappears
00167                 return;
00168         }
00169         if ( self->NPC && self->NPC->timeOfDeath <= level.time )
00170         {
00171                 self->NPC->timeOfDeath = level.time + 1000;
00172                 // Only do all of this nonsense for Scav boys ( and girls )
00174         //              || self->client->playerTeam == NPCTEAM_HIROGEN || self->client->playerTeam == NPCTEAM_MALON )
00175                 // should I check NPC_class here instead of TEAM ? - dmv
00176                 if( self->client->playerTeam == NPCTEAM_ENEMY || self->client->NPC_class == CLASS_PROTOCOL )
00177                 {
00178                         self->nextthink = level.time + FRAMETIME; // try back in a second
00179 
00180                         /*
00181                         if ( DistanceSquared( g_entities[0].r.currentOrigin, self->r.currentOrigin ) <= REMOVE_DISTANCE_SQR )
00182                         {
00183                                 return;
00184                         }
00185 
00186                         if ( (InFOV( self, &g_entities[0], 110, 90 )) ) // generous FOV check
00187                         {
00188                                 if ( (NPC_ClearLOS2( &g_entities[0], self->r.currentOrigin )) )
00189                                 {
00190                                         return;
00191                                 }
00192                         }
00193                         */
00194                         //Don't care about this for MP I guess.
00195                 }
00196 
00197                 //FIXME: there are some conditions - such as heavy combat - in which we want
00198                 //                      to remove the bodies... but in other cases it's just weird, like
00199                 //                      when they're right behind you in a closed room and when they've been
00200                 //                      placed as dead NPCs by a designer...
00201                 //                      For now we just assume that a corpse with no enemy was 
00202                 //                      placed in the map as a corpse
00203                 if ( self->enemy )
00204                 {
00205                         //if ( !self->taskManager || !self->taskManager->IsRunning() )
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                                 {//not being held by a Rancor
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 }

void NPC_RunBehavior int  team,
int  bState
 

Definition at line 1384 of file NPC.c.

References AEL_DANGER_GREAT, Boba_Flying(), BS_CINEMATIC, BS_FLEE, BS_HUNT_AND_KILL, gNPC_t::charmedTime, CLASS_ATST, CLASS_BOBAFETT, CLASS_GALAKMECH, CLASS_HOWLER, CLASS_INTERROGATOR, CLASS_JAWA, CLASS_MARK1, CLASS_MARK2, CLASS_MINEMONSTER, CLASS_PROBE, CLASS_PROTOCOL, CLASS_RANCOR, CLASS_REMOTE, CLASS_SEEKER, CLASS_SENTRY, CLASS_UGNAUGHT, CLASS_VEHICLE, CLASS_WAMPA, gentity_s::client, entityShared_t::currentOrigin, gentity_s::enemy, level, gentity_s::m_pVehicle, NPC, NPC_BehaviorSet_ATST(), NPC_BehaviorSet_Charmed(), NPC_BehaviorSet_Default(), NPC_BehaviorSet_Droid(), NPC_BehaviorSet_Grenadier(), NPC_BehaviorSet_Howler(), NPC_BehaviorSet_ImperialProbe(), NPC_BehaviorSet_Interrogator(), NPC_BehaviorSet_Jedi(), NPC_BehaviorSet_Mark1(), NPC_BehaviorSet_Mark2(), NPC_BehaviorSet_MineMonster(), NPC_BehaviorSet_Rancor(), NPC_BehaviorSet_Remote(), NPC_BehaviorSet_Seeker(), NPC_BehaviorSet_Sentry(), NPC_BehaviorSet_Sniper(), NPC_BehaviorSet_Stormtrooper(), NPC_BSCinematic(), NPC_BSDefault(), NPC_BSEmplaced(), NPC_BSFlee(), NPC_BSGM_Default(), NPC_BSWampa_Default(), NPC_CheckCharmed(), NPC_CheckSurrender(), gclient_s::NPC_class, entityState_s::NPC_class, NPC_StartFlee(), NPC_UpdateAngles(), NPCInfo, NPCTEAM_ENEMY, NPCTEAM_NEUTRAL, gclient_s::ps, qboolean, qfalse, qtrue, gentity_s::r, gentity_s::s, SCF_ALT_FIRE, SCF_FORCED_MARCH, gNPC_t::scriptFlags, TID_MOVE_NAV, level_locals_t::time, trap_ICARUS_TaskIDPending(), entityState_s::weapon, playerState_s::weapon, WP_DISRUPTOR, WP_EMPLACED_GUN, WP_NONE, WP_SABER, WP_STUN_BATON, and WP_THERMAL.

Referenced by NPC_ExecuteBState().

01385 {
01386         qboolean dontSetAim = qfalse;
01387 
01388         if (NPC->s.NPC_class == CLASS_VEHICLE &&
01389                 NPC->m_pVehicle)
01390         { //vehicles don't do AI!
01391                 return;
01392         }
01393 
01394         if ( bState == BS_CINEMATIC )
01395         {
01396                 NPC_BSCinematic();
01397         }
01398         else if ( NPC->client->ps.weapon == WP_EMPLACED_GUN )
01399         {
01400                 NPC_BSEmplaced();
01401                 NPC_CheckCharmed();
01402                 return;
01403         }
01404         else if ( NPC->client->ps.weapon == WP_SABER )
01405         {//jedi
01406                 NPC_BehaviorSet_Jedi( bState );
01407                 dontSetAim = qtrue;
01408         }
01409         else if ( NPC->client->NPC_class == CLASS_WAMPA )
01410         {//wampa
01411                 NPC_BSWampa_Default();
01412         }
01413         else if ( NPC->client->NPC_class == CLASS_RANCOR )
01414         {//rancor
01415                 NPC_BehaviorSet_Rancor( bState );
01416         }
01417         else if ( NPC->client->NPC_class == CLASS_REMOTE )
01418         {
01419                 NPC_BehaviorSet_Remote( bState );
01420         }
01421         else if ( NPC->client->NPC_class == CLASS_SEEKER )
01422         {
01423                 NPC_BehaviorSet_Seeker( bState );
01424         }
01425         else if ( NPC->client->NPC_class == CLASS_BOBAFETT )
01426         {//bounty hunter
01427                 if ( Boba_Flying( NPC ) )
01428                 {
01429                         NPC_BehaviorSet_Seeker(bState);
01430                 }
01431                 else
01432                 {
01433                         NPC_BehaviorSet_Jedi( bState );
01434                 }
01435                 dontSetAim = qtrue;
01436         }
01437         else if ( NPCInfo->scriptFlags & SCF_FORCED_MARCH )
01438         {//being forced to march
01439                 NPC_BSDefault();
01440         }
01441         else
01442         {
01443                 switch( team )
01444                 {
01445                 
01446         //      case NPCTEAM_SCAVENGERS:
01447         //      case NPCTEAM_IMPERIAL:
01448         //      case NPCTEAM_KLINGON:
01449         //      case NPCTEAM_HIROGEN:
01450         //      case NPCTEAM_MALON:
01451                 // not sure if TEAM_ENEMY is appropriate here, I think I should be using NPC_class to check for behavior - dmv
01452                 case NPCTEAM_ENEMY:
01453                         // special cases for enemy droids
01454                         switch( NPC->client->NPC_class)
01455                         {
01456                         case CLASS_ATST:
01457                                 NPC_BehaviorSet_ATST( bState );
01458                                 return;
01459                         case CLASS_PROBE:
01460                                 NPC_BehaviorSet_ImperialProbe(bState);
01461                                 return;
01462                         case CLASS_REMOTE:
01463                                 NPC_BehaviorSet_Remote( bState );
01464                                 return;
01465                         case CLASS_SENTRY:
01466                                 NPC_BehaviorSet_Sentry(bState);
01467                                 return;
01468                         case CLASS_INTERROGATOR:
01469                                 NPC_BehaviorSet_Interrogator( bState );
01470                                 return;
01471                         case CLASS_MINEMONSTER:
01472                                 NPC_BehaviorSet_MineMonster( bState );
01473                                 return;
01474                         case CLASS_HOWLER:
01475                                 NPC_BehaviorSet_Howler( bState );
01476                                 return;
01477                         case CLASS_MARK1:
01478                                 NPC_BehaviorSet_Mark1( bState );
01479                                 return;
01480                         case CLASS_MARK2:
01481                                 NPC_BehaviorSet_Mark2( bState );
01482                                 return;
01483                         case CLASS_GALAKMECH:
01484                                 NPC_BSGM_Default();
01485                                 return;
01486 
01487                         }
01488 
01489                         if ( NPC->enemy && NPC->s.weapon == WP_NONE && bState != BS_HUNT_AND_KILL && !trap_ICARUS_TaskIDPending( NPC, TID_MOVE_NAV ) )
01490                         {//if in battle and have no weapon, run away, fixme: when in BS_HUNT_AND_KILL, they just stand there
01491                                 if ( bState != BS_FLEE )
01492                                 {
01493                                         NPC_StartFlee( NPC->enemy, NPC->enemy->r.currentOrigin, AEL_DANGER_GREAT, 5000, 10000 );
01494                                 }
01495                                 else
01496                                 {
01497                                         NPC_BSFlee();
01498                                 }
01499                                 return;
01500                         }
01501                         if ( NPC->client->ps.weapon == WP_SABER )
01502                         {//special melee exception
01503                                 NPC_BehaviorSet_Default( bState );
01504                                 return;
01505                         }
01506                         if ( NPC->client->ps.weapon == WP_DISRUPTOR && (NPCInfo->scriptFlags & SCF_ALT_FIRE) )
01507                         {//a sniper
01508                                 NPC_BehaviorSet_Sniper( bState );
01509                                 return;
01510                         }
01511                         if ( NPC->client->ps.weapon == WP_THERMAL || NPC->client->ps.weapon == WP_STUN_BATON )//FIXME: separate AI for melee fighters
01512                         {//a grenadier
01513                                 NPC_BehaviorSet_Grenadier( bState );
01514                                 return;
01515                         }
01516                         if ( NPC_CheckSurrender() )
01517                         {
01518                                 return;
01519                         }
01520                         NPC_BehaviorSet_Stormtrooper( bState );
01521                         break;
01522 
01523                 case NPCTEAM_NEUTRAL: 
01524 
01525                         // special cases for enemy droids
01526                         if ( NPC->client->NPC_class == CLASS_PROTOCOL || NPC->client->NPC_class == CLASS_UGNAUGHT ||
01527                                 NPC->client->NPC_class == CLASS_JAWA)
01528                         {
01529                                 NPC_BehaviorSet_Default(bState);
01530                         }
01531                         else if ( NPC->client->NPC_class == CLASS_VEHICLE )
01532                         {
01533                                 // TODO: Add vehicle behaviors here.
01534                                 NPC_UpdateAngles( qtrue, qtrue );//just face our spawn angles for now
01535                         }
01536                         else
01537                         {
01538                                 // Just one of the average droids
01539                                 NPC_BehaviorSet_Droid( bState );
01540                         }
01541                         break;
01542 
01543                 default:
01544                         if ( NPC->client->NPC_class == CLASS_SEEKER )
01545                         {
01546                                 NPC_BehaviorSet_Seeker(bState);
01547                         }
01548                         else
01549                         {
01550                                 if ( NPCInfo->charmedTime > level.time )
01551                                 {
01552                                         NPC_BehaviorSet_Charmed( bState );
01553                                 }
01554                                 else
01555                                 {
01556                                         NPC_BehaviorSet_Default( bState );
01557                                 }
01558                                 NPC_CheckCharmed();
01559                                 dontSetAim = qtrue;
01560                         }
01561                         break;
01562                 }
01563         }
01564 }

void NPC_SetAnim gentity_t ent,
int  type,
int  anim,
int  priority
 

void NPC_SetLookTarget gentity_t self,
int  entNum,
int  clearTime
 

Definition at line 1632 of file NPC_utils.c.

01633 {
01634         if ( !self->client )
01635         {
01636                 return;
01637         }
01638 
01639         if ( (self->client->ps.eFlags2&EF2_HELD_BY_MONSTER) )
01640         {//lookTarget is set by and to the monster that's holding you, no other operations can change that
01641                 return;
01642         }
01643 
01644         self->client->renderInfo.lookTarget = entNum;
01645         self->client->renderInfo.lookTargetClearTime = clearTime;
01646 }

void NPC_ShowDebugInfo void   ) 
 

Definition at line 664 of file NPC.c.

References entityShared_t::currentOrigin, FOFS, G_Cube(), g_entities, G_Find(), gentity_t, entityShared_t::maxs, entityShared_t::mins, NPCDEBUG_RED, NULL, gentity_s::r, showBBoxes, trap_InPVS(), vec3_t, and VectorAdd.

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 }

void NPC_TempLookTarget gentity_t self,
int  lookEntNum,
int  minLookTime,
int  maxLookTime
 

Definition at line 661 of file NPC_reactions.c.

00662 {
00663         if ( !self->client )
00664         {
00665                 return;
00666         }
00667 
00668         if ( (self->client->ps.eFlags2&EF2_HELD_BY_MONSTER) )
00669         {//lookTarget is set by and to the monster that's holding you, no other operations can change that
00670                 return;
00671         }
00672 
00673         if ( !minLookTime )
00674         {
00675                 minLookTime = 1000;
00676         }
00677 
00678         if ( !maxLookTime )
00679         {
00680                 maxLookTime = 1000;
00681         }
00682 
00683         if ( !NPC_CheckLookTarget( self ) )
00684         {//Not already looking at something else
00685                 //Look at him for 1 to 3 seconds
00686                 NPC_SetLookTarget( self, lookEntNum, level.time + Q_irand( minLookTime, maxLookTime ) );
00687         }
00688 }

void NPC_Think gentity_t self  ) 
 

Definition at line 1826 of file NPC.c.

References usercmd_s::buttons, CLASS_VEHICLE, gentity_s::client, ClientThink(), clientPersistant_t::cmd, Com_Printf(), entityShared_t::currentOrigin, debugNPCFreeze, ET_NPC, entityState_s::eType, usercmd_s::forwardmove, FRAMETIME, G_DroidSounds(), g_entities, g_spskill, gentity_t, GetTime(), gentity_s::health, vmCvar_t::integer, gentity_s::inuse, gNPC_t::last_ucmd, level, entityState_s::m_iVehicleNum, playerState_s::m_iVehicleNum, gentity_s::m_pVehicle, Vehicle_s::m_ucmd, MAX_CLIENTS, memcpy(), memset(), playerState_s::moveDir, gentity_s::next_roff_time, gNPC_t::nextBStateThink, gentity_s::nextthink, NPC, gentity_s::NPC, NPC_ApplyRoff(), gclient_s::NPC_class, entityState_s::NPC_class, NPC_ExecuteBState(), gentity_s::NPC_type, NPC_UpdateAngles(), NPCInfo, entityState_s::number, playerState_s::origin, gclient_s::pers, playerState_s::pm_flags, PMF_FOLLOW, gclient_s::ps, qtrue, gentity_s::r, gNPC_t::rank, RANK_LT_JG, usercmd_s::rightmove, gentity_s::s, S_COLOR_RED, usercmd_s::serverTime, gclient_s::sess, clientSession_t::sessionTeam, SetNPCGlobals(), startTime, SVF_ICARUS_FREEZE, entityShared_t::svFlags, gentity_s::targetname, TEAM_SPECTATOR, level_locals_t::time, trap_ICARUS_MaintainTaskManager(), ucmd, usercmd_s::upmove, usercmd_t, vmCvar_t::value, vec3_t, VectorClear, VectorCopy, vtos(), entityState_s::weapon, and WP_SABER.

Referenced by NPC_Begin().

01827 {
01828         vec3_t  oldMoveDir;
01829         int i = 0;
01830         gentity_t *player;
01831 
01832         self->nextthink = level.time + FRAMETIME;
01833 
01834         SetNPCGlobals( self );
01835 
01836         memset( &ucmd, 0, sizeof( ucmd ) );
01837 
01838         VectorCopy( self->client->ps.moveDir, oldMoveDir );
01839         if (self->s.NPC_class != CLASS_VEHICLE)
01840         { //YOU ARE BREAKING MY PREDICTION. Bad clear.
01841                 VectorClear( self->client->ps.moveDir );
01842         }
01843 
01844         if(!self || !self->NPC || !self->client)
01845         {
01846                 return;
01847         }
01848 
01849         // dead NPCs have a special think, don't run scripts (for now)
01850         //FIXME: this breaks deathscripts
01851         if ( self->health <= 0 ) 
01852         {
01853                 DeadThink();
01854                 if ( NPCInfo->nextBStateThink <= level.time )
01855                 {
01856                         trap_ICARUS_MaintainTaskManager(self->s.number);
01857                 }
01858                 VectorCopy(self->r.currentOrigin, self->client->ps.origin);
01859                 return;
01860         }
01861 
01862         // see if NPC ai is frozen
01863         if ( debugNPCFreeze.value || (NPC->r.svFlags&SVF_ICARUS_FREEZE) ) 
01864         {
01865                 NPC_UpdateAngles( qtrue, qtrue );
01866                 ClientThink(self->s.number, &ucmd);
01867                 //VectorCopy(self->s.origin, self->s.origin2 );
01868                 VectorCopy(self->r.currentOrigin, self->client->ps.origin);
01869                 return;
01870         }
01871 
01872         self->nextthink = level.time + FRAMETIME/2;
01873 
01874 
01875         while (i < MAX_CLIENTS)
01876         {
01877                 player = &g_entities[i];
01878 
01879                 if (player->inuse && player->client && player->client->sess.sessionTeam != TEAM_SPECTATOR &&
01880                         !(player->client->ps.pm_flags & PMF_FOLLOW))
01881                 {
01882                         //if ( player->client->ps.viewEntity == self->s.number )
01883                         if (0) //rwwFIXMEFIXME: Allow controlling ents
01884                         {//being controlled by player
01885                                 G_DroidSounds( self );
01886                                 //FIXME: might want to at least make sounds or something?
01887                                 //NPC_UpdateAngles(qtrue, qtrue);
01888                                 //Which ucmd should we send?  Does it matter, since it gets overridden anyway?
01889                                 NPCInfo->last_ucmd.serverTime = level.time - 50;
01890                                 ClientThink( NPC->s.number, &ucmd );
01891                                 //VectorCopy(self->s.origin, self->s.origin2 );
01892                                 VectorCopy(self->r.currentOrigin, self->client->ps.origin);
01893                                 return;
01894                         }
01895                 }
01896                 i++;
01897         }
01898 
01899         if ( self->client->NPC_class == CLASS_VEHICLE)
01900         {
01901                 if (self->client->ps.m_iVehicleNum)
01902                 {//we don't think on our own
01903                         //well, run scripts, though...
01904                         trap_ICARUS_MaintainTaskManager(self->s.number);
01905                         return;
01906                 }
01907                 else
01908                 {
01909                         VectorClear(self->client->ps.moveDir);
01910                         self->client->pers.cmd.forwardmove = 0;
01911                         self->client->pers.cmd.rightmove = 0;
01912                         self->client->pers.cmd.upmove = 0;
01913                         self->client->pers.cmd.buttons = 0;
01914                         memcpy(&self->m_pVehicle->m_ucmd, &self->client->pers.cmd, sizeof(usercmd_t));
01915                 }
01916         }
01917         else if ( NPC->s.m_iVehicleNum )
01918         {//droid in a vehicle?
01919                 G_DroidSounds( self );
01920         }
01921 
01922         if ( NPCInfo->nextBStateThink <= level.time 
01923                 && !NPC->s.m_iVehicleNum )//NPCs sitting in Vehicles do NOTHING
01924         {
01925 #if     AI_TIMERS
01926                 int     startTime = GetTime(0);
01927 #endif//        AI_TIMERS
01928                 if ( NPC->s.eType != ET_NPC )
01929                 {//Something drastic happened in our script
01930                         return;
01931                 }
01932 
01933                 if ( NPC->s.weapon == WP_SABER && g_spskill.integer >= 2 && NPCInfo->rank > RANK_LT_JG )
01934                 {//Jedi think faster on hard difficulty, except low-rank (reborn)
01935                         NPCInfo->nextBStateThink = level.time + FRAMETIME/2;
01936                 }
01937                 else
01938                 {//Maybe even 200 ms?
01939                         NPCInfo->nextBStateThink = level.time + FRAMETIME;
01940                 }
01941 
01942                 //nextthink is set before this so something in here can override it
01943                 if (self->s.NPC_class != CLASS_VEHICLE ||
01944                         !self->m_pVehicle)
01945                 { //ok, let's not do this at all for vehicles.
01946                         NPC_ExecuteBState( self );
01947                 }
01948 
01949 #if     AI_TIMERS
01950                 int addTime = GetTime( startTime );
01951                 if ( addTime > 50 )
01952                 {
01953                         Com_Printf( S_COLOR_RED"ERROR: NPC number %d, %s %s at %s, weaponnum: %d, using %d of AI time!!!\n", NPC->s.number, NPC->NPC_type, NPC->targetname, vtos(NPC->r.currentOrigin), NPC->s.weapon, addTime );
01954                 }
01955                 AITime += addTime;
01956 #endif//        AI_TIMERS
01957         }
01958         else
01959         {
01960                 VectorCopy( oldMoveDir, self->client->ps.moveDir );
01961                 //or use client->pers.lastCommand?
01962                 NPCInfo->last_ucmd.serverTime = level.time - 50;
01963                 if ( !NPC->next_roff_time || NPC->next_roff_time < level.time )
01964                 {//If we were following a roff, we don't do normal pmoves.
01965                         //FIXME: firing angles (no aim offset) or regular angles?
01966                         NPC_UpdateAngles(qtrue, qtrue);
01967                         memcpy( &ucmd, &NPCInfo->last_ucmd, sizeof( usercmd_t ) );
01968                         ClientThink(NPC->s.number, &ucmd);
01969                 }
01970                 else
01971                 {
01972                         NPC_ApplyRoff();
01973                 }
01974                 //VectorCopy(self->s.origin, self->s.origin2 );
01975         }
01976         //must update icarus *every* frame because of certain animation completions in the pmove stuff that can leave a 50ms gap between ICARUS animation commands
01977         trap_ICARUS_MaintainTaskManager(self->s.number);
01978         VectorCopy(self->r.currentOrigin, self->client->ps.origin);
01979 }

void pitch_roll_for_slope gentity_t forwhom,
vec3_t  pass_slope
 

Referenced by CorpsePhysics(), and G_RunObject().

void PM_SetLegsAnimTimer gentity_t ent,
int *  legsAnimTimer,
int  time
 

void PM_SetTorsoAnimTimer gentity_t ent,
int *  torsoAnimTimer,
int  time
 

void Q3_DebugPrint int  level,
const char *  format,
... 
 

void RestoreNPCGlobals void   ) 
 

Definition at line 638 of file NPC.c.

References _saved_client, _saved_NPC, _saved_NPCInfo, _saved_ucmd, client, memcpy(), NPC, NPCInfo, ucmd, and usercmd_t.

Referenced by G_StartFlee(), Mark1_dying(), NPC_Pain(), NPC_Remote_Pain(), NPC_Seeker_Pain(), NPC_Touch(), NPC_Use(), and ST_Commander().

00639 {
00640         NPC = _saved_NPC;
00641         NPCInfo = _saved_NPCInfo;
00642         client = _saved_client;
00643         memcpy( &ucmd, &_saved_ucmd, sizeof( usercmd_t ) );
00644 }

void SaveNPCGlobals void   ) 
 

Definition at line 630 of file NPC.c.

References _saved_client, _saved_NPC, _saved_NPCInfo, _saved_ucmd, client, memcpy(), NPC, NPCInfo, ucmd, and usercmd_t.

Referenced by G_StartFlee(), Mark1_dying(), NPC_Pain(), NPC_Remote_Pain(), NPC_Seeker_Pain(), NPC_Touch(), NPC_Use(), and ST_Commander().

00631 {
00632         _saved_NPC = NPC;
00633         _saved_NPCInfo = NPCInfo;
00634         _saved_client = client;
00635         memcpy( &_saved_ucmd, &ucmd, sizeof( usercmd_t ) );
00636 }

void SetNPCGlobals gentity_t ent  ) 
 

Definition at line 617 of file NPC.c.

References client, gentity_t, memset(), NPC, NPCInfo, ucmd, and usercmd_t.

Referenced by G_StartFlee(), Mark1_dying(), NPC_Begin(), NPC_Pain(), NPC_Remote_Pain(), NPC_Seeker_Pain(), NPC_Think(), NPC_Touch(), NPC_Use(), and ST_Commander().

00618 {
00619         NPC = ent;
00620         NPCInfo = ent->NPC;
00621         client = ent->client;
00622         memset( &ucmd, 0, sizeof( usercmd_t ) );
00623 }


Variable Documentation

gclient_t* _saved_client
 

Definition at line 627 of file NPC.c.

Referenced by RestoreNPCGlobals(), and SaveNPCGlobals().

gentity_t* _saved_NPC
 

Definition at line 625 of file NPC.c.

Referenced by RestoreNPCGlobals(), and SaveNPCGlobals().

gNPC_t* _saved_NPCInfo
 

Definition at line 626 of file NPC.c.

Referenced by RestoreNPCGlobals(), and SaveNPCGlobals().

usercmd_t _saved_ucmd
 

Definition at line 628 of file NPC.c.

Referenced by RestoreNPCGlobals(), and SaveNPCGlobals().

gclient_t* client
 

Definition at line 36 of file NPC.c.

Referenced by AddPowerDuelPlayers(), AddTournamentPlayer(), BeginIntermission(), BotAI(), BotAISetupClient(), BotAIShutdown(), BotAIShutdownClient(), BotAIStartFrame(), BotResetState(), BotSelectWeapon(), BroadcastObjectiveCompletion(), BroadcastTeamChange(), CG_AddSaberBlade(), CG_EntityEvent(), CG_InClientBitflags(), CG_IsMindTricked(), CG_PlayerAnimEventDo(), CG_SaberCompWork(), CG_ScorePlum(), CheckArmor(), ClearNPCGlobals(), ClientBegin(), ClientConnect(), ClientEvents(), ClientInactivityTimer(), ClientIntermissionThink(), ClientSpawn(), ClientThink_real(), ClientTimerActions(), ClientUserinfoChanged(), Cmd_TeamTask_f(), ForceThrow(), G_ClearClientLog(), G_Damage(), G_GetDuelWinner(), G_InitSessionData(), G_IsMindTricked(), G_LogWeaponDamage(), G_LogWeaponDeath(), G_LogWeaponFire(), G_LogWeaponItem(), G_LogWeaponKill(), G_LogWeaponPickup(), G_LogWeaponPowerup(), G_ReadSessionData(), G_WriteClientSessionData(), HaveWeapon(), NPC_ApplyWeaponFireDelay(), NPC_Begin(), NPC_BSFace(), NPC_BSPointShoot(), NPC_BSShoot(), NPC_CheckCanAttack(), NPC_ExecuteBState(), NPC_FacePosition(), NPC_KeepCurrentFacing(), NPC_StandTrackAndShoot(), NPC_UpdateAngles(), NPC_UpdateFiringAngles(), P_DamageFeedback(), P_SetTwitchInfo(), Pickup_Powerup(), player_die(), RestoreNPCGlobals(), SaveNPCGlobals(), ScanForEnemies(), SetLeader(), SetNPCGlobals(), SetTeam(), ShootThink(), Siege_DefendFromAttackers(), SiegeBroadcast_OBJECTIVECOMPLETE(), SiegeObjectiveCompleted(), SpectatorThink(), StandardBotAI(), trap_BotEnterChat(), trap_BotSetChatName(), trap_EA_Action(), trap_EA_Alt_Attack(), trap_EA_Attack(), trap_EA_Command(), trap_EA_Crouch(), trap_EA_DelayedJump(), trap_EA_EndRegular(), trap_EA_ForcePower(), trap_EA_Gesture(), trap_EA_GetInput(), trap_EA_Jump(), trap_EA_Move(), trap_EA_MoveBack(), trap_EA_MoveDown(), trap_EA_MoveForward(), trap_EA_MoveLeft(), trap_EA_MoveRight(), trap_EA_MoveUp(), trap_EA_ResetInput(), trap_EA_Respawn(), trap_EA_Say(), trap_EA_SayTeam(), trap_EA_SelectWeapon(), trap_EA_Talk(), trap_EA_Use(), trap_EA_View(), Use_Target_Escapetrig(), and WeaponThink().

visibility_t enemyVisibility
 

Definition at line 38 of file NPC.c.

Referenced by NPC_BSAdvanceFight(), NPC_BSFollowLeader(), NPC_BSHuntAndKill(), NPC_BSShoot(), NPC_CheckCanAttack(), and NPC_CheckPossibleEnemy().

int eventClearTime
 

Definition at line 44 of file NPC.c.

vmCvar_t g_saberRealisticCombat
 

Definition at line 31 of file NPC.c.

gentity_t* NPC
 

Definition at line 34 of file NPC.c.

Referenced by ATST_Attack(), ATST_Hunt(), ATST_Idle(), ATST_Patrol(), ATST_Ranged(), Boba_ChangeWeapon(), Boba_FireDecide(), Boba_StartFlameThrower(), CanSee(), ClearNPCGlobals(), Droid_Pain(), Droid_Patrol(), Droid_Spin(), GM_StartGloat(), Grenadier_EvaluateShot(), Howler_Attack(), Howler_Combat(), Howler_Move(), Howler_Patrol(), Howler_TryDamage(), IdealDistance(), ImperialProbe_AttackDecision(), ImperialProbe_FireBlaster(), ImperialProbe_Hunt(), ImperialProbe_MaintainHeight(), ImperialProbe_Patrol(), ImperialProbe_Ranged(), ImperialProbe_Strafe(), ImperialProbe_Wait(), Interrogator_Attack(), Interrogator_Hunt(), Interrogator_Idle(), Interrogator_MaintainHeight(), Interrogator_Melee(), Interrogator_PartsMove(), Interrogator_Strafe(), InVisrange(), Jedi_CheckAmbushPlayer(), Jedi_CheckCloak(), Jedi_CheckDanger(), Jedi_SaberBlockGo(), Mark1_AttackDecision(), Mark1_BlasterAttack(), Mark1_FireBlaster(), Mark1_FireRocket(), Mark1_Hunt(), Mark1_Idle(), Mark1_Patrol(), Mark1_RocketAttack(), Mark1Dead_FireBlaster(), Mark1Dead_FireRocket(), Mark2_AttackDecision(), Mark2_BlasterAttack(), Mark2_FireBlaster(), Mark2_Hunt(), Mark2_Patrol(), MineMonster_Attack(), MineMonster_Combat(), MineMonster_Move(), MineMonster_Patrol(), MineMonster_TryDamage(), NAV_AvoidCollision(), NAV_MicroError(), NAV_TestBestNode(), NPC_AimAdjust(), NPC_AimWiggle(), NPC_ApplyRoff(), NPC_ApplyWeaponFireDelay(), NPC_AttackDebounceForWeapon(), NPC_BSAdvanceFight(), NPC_BSATST_Default(), NPC_BSCinematic(), NPC_BSDefault(), NPC_BSEmplaced(), NPC_BSFace(), NPC_BSFlee(), NPC_BSFollowLeader(), NPC_BSGM_Attack(), NPC_BSGM_Default(), NPC_BSGrenadier_Attack(), NPC_BSGrenadier_Default(), NPC_BSGrenadier_Patrol(), NPC_BSHowler_Default(), NPC_BSHuntAndKill(), NPC_BSImperialProbe_Default(), NPC_BSInterrogator_Default(), NPC_BSJedi_Default(), NPC_BSJedi_FollowLeader(), NPC_BSJump(), NPC_BSMark1_Default(), NPC_BSMark2_Default(), NPC_BSMineMonster_Default(), NPC_BSMove(), NPC_BSNoClip(), NPC_BSPatrol(), NPC_BSPointShoot(), NPC_BSRancor_Default(), NPC_BSRemote_Default(), NPC_BSRemove(), NPC_BSRunAndShoot(), NPC_BSSearch(), NPC_BSSearchStart(), NPC_BSSeeker_Default(), NPC_BSSentry_Default(), NPC_BSSleep(), NPC_BSSniper_Attack(), NPC_BSSniper_Default(), NPC_BSSniper_Patrol(), NPC_BSST_Attack(), NPC_BSST_Default(), NPC_BSST_Investigate(), NPC_BSST_Patrol(), NPC_BSST_Sleep(), NPC_BSStandAndShoot(), NPC_BSStandGuard(), NPC_BSWampa_Default(), NPC_BSWander(), NPC_CheckAlertEvents(), NPC_CheckAttackHold(), NPC_CheckAttackScript(), NPC_CheckCanAttack(), NPC_CheckCanAttackExt(), NPC_CheckCharmed(), NPC_CheckCombatMove(), NPC_CheckEnemy(), NPC_CheckEnemyStealth(), NPC_CheckForDanger(), NPC_CheckGetNewWeapon(), NPC_CheckInSolid(), NPC_CheckInvestigate(), NPC_CheckPlayerTeamStealth(), NPC_CheckPossibleEnemy(), NPC_CheckSurrender(), NPC_CheckVisibility(), NPC_ClearLOS(), NPC_ClearLOS2(), NPC_ClearLOS3(), NPC_ClearLOS4(), NPC_ClearLOS5(), NPC_ClearPathToGoal(), NPC_ClearShot(), NPC_EnemyRangeFromBolt(), NPC_EnemyTooFar(), NPC_EntRangeFromBolt(), NPC_EvaluateShot(), NPC_ExecuteBState(), NPC_FaceEnemy(), NPC_FacePosition(), NPC_FindCombatPoint(), NPC_FindEnemy(), NPC_GetEntsNearBolt(), NPC_GetMoveDirection(), NPC_GetMoveDirectionAltRoute(), NPC_GetMoveInformation(), NPC_GM_StartLaser(), NPC_HandleAIFlags(), NPC_LostEnemyDecideChase(), NPC_MaxDistSquaredForWeapon(), NPC_MoveDirClear(), NPC_MoveToGoal(), NPC_Pain(), NPC_ParseParms(), NPC_PickAlly(), NPC_PickEnemy(), NPC_PickEnemyExt(), NPC_ReachedGoal(), NPC_RunBehavior(), NPC_SearchForWeapons(), NPC_Sentry_Patrol(), NPC_SetPickUpGoal(), NPC_ShotEntity(), NPC_SlideMoveToGoal(), NPC_ST_SayMovementSpeech(), NPC_StandTrackAndShoot(), NPC_StartFlee(), NPC_Surrender(), NPC_TargetVisible(), NPC_Think(), NPC_Touch(), NPC_UpdateAngles(), NPC_UpdateFiringAngles(), NPC_Use(), NPC_ValidEnemy(), R2D2_PartsMove(), R2D2_TurnAnims(), Rancor_Attack(), Rancor_Bite(), Rancor_CheckDropVictim(), Rancor_Combat(), Rancor_Crush(), Rancor_Move(), Rancor_Patrol(), Rancor_Smash(), Rancor_Swing(), ReachedGoal(), Remote_Attack(), Remote_Fire(), Remote_Hunt(), Remote_MaintainHeight(), Remote_Patrol(), Remote_Ranged(), Remote_Strafe(), RestoreNPCGlobals(), SaveNPCGlobals(), Seeker_Attack(), Seeker_FindEnemy(), Seeker_Fire(), Seeker_FollowOwner(), Seeker_Hunt(), Seeker_MaintainHeight(), Seeker_Ranged(), Seeker_Strafe(), Sentry_AttackDecision(), Sentry_Fire(), Sentry_Hunt(), Sentry_Idle(), Sentry_MaintainHeight(), Sentry_RangedAttack(), Sentry_Strafe(), SetNPCGlobals(), ShootThink(), Sniper_EvaluateShot(), Sniper_FaceEnemy(), Sniper_StartHide(), Sniper_UpdateEnemyPos(), ST_Commander(), ST_GetCPFlags(), ST_HuntEnemy(), ST_ResolveBlockedShot(), ValidEnemy(), Wampa_Attack(), Wampa_Combat(), Wampa_Move(), Wampa_Patrol(), Wampa_Slash(), and WeaponThink().

vec3_t NPCDEBUG_BLUE = {0.0, 0.0, 1.0}
 

Definition at line 658 of file NPC.c.

Referenced by NPC_BSJump().

vec3_t NPCDEBUG_GREEN = {0.0, 1.0, 0.0}
 

Definition at line 657 of file NPC.c.

vec3_t NPCDEBUG_LIGHT_BLUE = {0.3f, 0.7f, 1.0}
 

Definition at line 659 of file NPC.c.

vec3_t NPCDEBUG_RED = {1.0, 0.0, 0.0}
 

Definition at line 656 of file NPC.c.

Referenced by CG_PredictPlayerState(), and NPC_ShowDebugInfo().

gNPC_t* NPCInfo
 

Definition at line 35 of file NPC.c.

Referenced by ATST_Attack(), ATST_Hunt(), ATST_Ranged(), Boba_FireDecide(), ClearNPCGlobals(), Droid_Pain(), Droid_Patrol(), Droid_Run(), Droid_Spin(), Howler_Combat(), Howler_Move(), Howler_Patrol(), IdealDistance(), ImperialProbe_AttackDecision(), ImperialProbe_Hunt(), ImperialProbe_MaintainHeight(), ImperialProbe_Ranged(), ImperialProbe_Strafe(), ImperialProbe_Wait(), Interrogator_Attack(), Interrogator_Hunt(), Interrogator_MaintainHeight(), Interrogator_Melee(), Interrogator_PartsMove(), Interrogator_Strafe(), InVisrange(), Jedi_CheckAmbushPlayer(), Jedi_CheckDanger(), Jedi_QuickReactions(), Mark1_BlasterAttack(), Mark1_FireBlaster(), Mark1_Hunt(), Mark2_AttackDecision(), Mark2_BlasterAttack(), Mark2_Hunt(), MineMonster_Combat(), MineMonster_Move(), MineMonster_Patrol(), NAV_ClearPathToPoint(), NAVNEW_MoveToGoal(), NPC_AimAdjust(), NPC_AimWiggle(), NPC_ApplyScriptFlags(), NPC_AttackDebounceForWeapon(), NPC_Begin(), NPC_BSAdvanceFight(), NPC_BSATST_Default(), NPC_BSCinematic(), NPC_BSDefault(), NPC_BSDroid_Default(), NPC_BSEmplaced(), NPC_BSFace(), NPC_BSFlee(), NPC_BSFollowLeader(), NPC_BSGM_Attack(), NPC_BSGM_Default(), NPC_BSGrenadier_Attack(), NPC_BSGrenadier_Default(), NPC_BSGrenadier_Patrol(), NPC_BSHowler_Default(), NPC_BSHuntAndKill(), NPC_BSImperialProbe_Default(), NPC_BSJedi_Default(), NPC_BSJedi_FollowLeader(), NPC_BSJump(), NPC_BSMark1_Default(), NPC_BSMark2_Default(), NPC_BSMineMonster_Default(), NPC_BSNoClip(), NPC_BSPatrol(), NPC_BSPointShoot(), NPC_BSRancor_Default(), NPC_BSRemote_Default(), NPC_BSRunAndShoot(), NPC_BSSearch(), NPC_BSSearchStart(), NPC_BSSentry_Default(), NPC_BSSniper_Attack(), NPC_BSSniper_Patrol(), NPC_BSST_Attack(), NPC_BSST_Default(), NPC_BSST_Investigate(), NPC_BSST_Patrol(), NPC_BSST_Sleep(), NPC_BSStandAndShoot(), NPC_BSStandGuard(), NPC_BSWampa_Default(), NPC_BSWander(), NPC_CheckAlertEvents(), NPC_CheckAttack(), NPC_CheckAttackHold(), NPC_CheckCanAttack(), NPC_CheckCanAttackExt(), NPC_CheckCharmed(), NPC_CheckCombatMove(), NPC_CheckDefend(), NPC_CheckEnemy(), NPC_CheckEnemyStealth(), NPC_CheckGetNewWeapon(), NPC_CheckInSolid(), NPC_CheckInvestigate(), NPC_CheckPossibleEnemy(), NPC_CheckVisibility(), NPC_ClearGoal(), NPC_ClearPathToGoal(), NPC_ExecuteBState(), NPC_FacePosition(), NPC_FindCombatPoint(), NPC_FindEnemy(), NPC_FindNearestEnemy(), NPC_FreeCombatPoint(), NPC_GetMoveDirection(), NPC_GetMoveDirectionAltRoute(), NPC_GetMoveInformation(), NPC_HandleAIFlags(), NPC_LostEnemyDecideChase(), NPC_MaxDistSquaredForWeapon(), NPC_MoveDirClear(), NPC_MoveToGoal(), NPC_Pain(), NPC_PickEnemy(), NPC_ReachedGoal(), NPC_ReactionTime(), NPC_RunBehavior(), NPC_SetCombatPoint(), NPC_SetGoal(), NPC_SetPickUpGoal(), NPC_SlideMoveToGoal(), NPC_ST_SayMovementSpeech(), NPC_ST_StoreMovementSpeech(), NPC_StandTrackAndShoot(), NPC_StartFlee(), NPC_Surrender(), NPC_TargetVisible(), NPC_Think(), NPC_Touch(), NPC_UpdateAngles(), NPC_UpdateFiringAngles(), NPC_UpdateShootAngles(), R2D2_TurnAnims(), Rancor_Combat(), Rancor_Idle(), Rancor_Move(), Rancor_Patrol(), ReachedGoal(), Remote_Attack(), Remote_Hunt(), Remote_MaintainHeight(), Remote_Ranged(), Remote_Strafe(), RestoreNPCGlobals(), SaveNPCGlobals(), Seeker_Attack(), Seeker_FollowOwner(), Seeker_Hunt(), Seeker_MaintainHeight(), Seeker_Ranged(), Seeker_Strafe(), Sentry_AttackDecision(), Sentry_Fire(), Sentry_Hunt(), Sentry_Idle(), Sentry_MaintainHeight(), Sentry_RangedAttack(), Sentry_Strafe(), SetGoal(), SetNPCGlobals(), ShootThink(), Sniper_FaceEnemy(), Sniper_UpdateEnemyPos(), ST_Commander(), ST_GetCPFlags(), ST_HuntEnemy(), ST_ResolveBlockedShot(), ST_TransferMoveGoal(), UpdateGoal(), Wampa_Combat(), Wampa_Idle(), Wampa_Move(), and Wampa_Patrol().

vec3_t playerMaxs
 

Definition at line 10 of file NPC.c.

vec3_t playerMins
 

Definition at line 9 of file NPC.c.

qboolean showBBoxes
 

Definition at line 655 of file NPC.c.

Referenced by Cmd_NPC_f(), NPC_BSJump(), and NPC_ShowDebugInfo().

usercmd_t ucmd
 

Definition at line 37 of file NPC.c.

Referenced by ATST_Patrol(), ATST_Ranged(), Boba_FireDecide(), BotInputToUserCommand(), ClientThink(), ClientThink_real(), CorpsePhysics(), Droid_Patrol(), Droid_Run(), Droid_Spin(), ForceJump(), G_AddPushVecToUcmd(), G_AttachToVehicle(), G_CheckClientIdle(), G_CheckMovingLoopingSounds(), G_SetAnim(), Howler_Patrol(), ImperialProbe_MaintainHeight(), ImperialProbe_Patrol(), Interrogator_MaintainHeight(), Mark1_Patrol(), Mark2_Patrol(), MineMonster_Idle(), MineMonster_Patrol(), NPC_ApplyScriptFlags(), NPC_Begin(), NPC_BSAdvanceFight(), NPC_BSDefault(), NPC_BSDroid_Default(), NPC_BSFlee(), NPC_BSFollowLeader(), NPC_BSGM_Attack(), NPC_BSGM_Patrol(), NPC_BSGrenadier_Attack(), NPC_BSGrenadier_Patrol(), NPC_BSHuntAndKill(), NPC_BSIdle(), NPC_BSJedi_Default(), NPC_BSJedi_FollowLeader(), NPC_BSJump(), NPC_BSNoClip(), NPC_BSPatrol(), NPC_BSPointShoot(), NPC_BSRunAndShoot(), NPC_BSSniper_Attack(), NPC_BSSniper_Patrol(), NPC_BSST_Attack(), NPC_BSST_Investigate(), NPC_BSST_Patrol(), NPC_BSStandAndShoot(), NPC_BSWampa_Default(), NPC_CheckAttackHold(), NPC_CheckAttackScript(), NPC_CheckCanAttack(), NPC_ExecuteBState(), NPC_FacePosition(), NPC_KeepCurrentFacing(), NPC_MoveDirClear(), NPC_MoveToGoal(), NPC_ReachedGoal(), NPC_Sentry_Patrol(), NPC_StandTrackAndShoot(), NPC_Think(), NPC_UpdateAngles(), NPC_UpdateFiringAngles(), PM_AdjustAngleForWallJump(), PM_AdjustAngleForWallRun(), PM_AdjustAngleForWallRunUp(), PM_AdjustAnglesForWallRunUpFlipAlt(), PM_MoveForKata(), PM_SaberMoveQuadrantForMovement(), PM_SetPMViewAngle(), PM_VehicleViewAngles(), Rancor_Idle(), Rancor_Patrol(), Remote_Patrol(), RestoreNPCGlobals(), SaveNPCGlobals(), Seeker_MaintainHeight(), Sentry_MaintainHeight(), SetNPCGlobals(), ShootThink(), SpectatorThink(), trap_BotUserCommand(), trap_GetUserCmd(), Wampa_Attack(), Wampa_Idle(), Wampa_Move(), Wampa_Patrol(), WeaponThink(), WP_DoSpecificPower(), WP_ForcePowersUpdate(), WP_GetVelocityForForceJump(), and WP_SaberStartMissileBlockCheck().