codemp/game/NPC_AI_Remote.c File Reference

#include "b_local.h"
#include "g_nav.h"

Go to the source code of this file.

Defines

#define VELOCITY_DECAY   0.85f
#define REMOTE_STRAFE_VEL   256
#define REMOTE_STRAFE_DIS   200
#define REMOTE_UPWARD_PUSH   32
#define REMOTE_FORWARD_BASE_SPEED   10
#define REMOTE_FORWARD_MULTIPLIER   5
#define MIN_MELEE_RANGE   320
#define MIN_MELEE_RANGE_SQR   ( MIN_MELEE_RANGE * MIN_MELEE_RANGE )
#define MIN_DISTANCE   80
#define MIN_DISTANCE_SQR   ( MIN_DISTANCE * MIN_DISTANCE )

Enumerations

enum  { LSTATE_NONE = 0 }

Functions

void Remote_Strafe (void)
void Remote_Idle (void)
void NPC_Remote_Precache (void)
void NPC_Remote_Pain (gentity_t *self, gentity_t *attacker, int damage)
void Remote_MaintainHeight (void)
void Remote_Hunt (qboolean visible, qboolean advance, qboolean retreat)
void Remote_Fire (void)
void Remote_Ranged (qboolean visible, qboolean advance, qboolean retreat)
void Remote_Attack (void)
void Remote_Patrol (void)
void NPC_BSRemote_Default (void)


Define Documentation

#define MIN_DISTANCE   80
 

Definition at line 282 of file NPC_AI_Remote.c.

#define MIN_DISTANCE_SQR   ( MIN_DISTANCE * MIN_DISTANCE )
 

Definition at line 283 of file NPC_AI_Remote.c.

#define MIN_MELEE_RANGE   320
 

Definition at line 279 of file NPC_AI_Remote.c.

#define MIN_MELEE_RANGE_SQR   ( MIN_MELEE_RANGE * MIN_MELEE_RANGE )
 

Definition at line 280 of file NPC_AI_Remote.c.

#define REMOTE_FORWARD_BASE_SPEED   10
 

Definition at line 170 of file NPC_AI_Remote.c.

Referenced by Remote_Hunt().

#define REMOTE_FORWARD_MULTIPLIER   5
 

Definition at line 171 of file NPC_AI_Remote.c.

Referenced by Remote_Hunt().

#define REMOTE_STRAFE_DIS   200
 

Definition at line 131 of file NPC_AI_Remote.c.

Referenced by Remote_Strafe().

#define REMOTE_STRAFE_VEL   256
 

Definition at line 130 of file NPC_AI_Remote.c.

Referenced by Remote_Strafe().

#define REMOTE_UPWARD_PUSH   32
 

Definition at line 132 of file NPC_AI_Remote.c.

Referenced by Remote_Strafe().

#define VELOCITY_DECAY   0.85f
 

Definition at line 6 of file NPC_AI_Remote.c.


Enumeration Type Documentation

anonymous enum
 

Enumeration values:
LSTATE_NONE 

Definition at line 10 of file NPC_AI_Remote.c.

00011 {
00012         LSTATE_NONE = 0,
00013 };


Function Documentation

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_Remote_Pain gentity_t self,
gentity_t attacker,
int  damage
 

Definition at line 29 of file NPC_AI_Remote.c.

References gentity_t, NPC_Pain(), Remote_Strafe(), RestoreNPCGlobals(), SaveNPCGlobals(), and SetNPCGlobals().

Referenced by NPC_PainFunc().

00030 {
00031         SaveNPCGlobals();
00032         SetNPCGlobals( self );
00033         Remote_Strafe();
00034         RestoreNPCGlobals();
00035 
00036         NPC_Pain( self, attacker, damage );
00037 }

void NPC_Remote_Precache void   ) 
 

Definition at line 17 of file NPC_AI_Remote.c.

References G_EffectIndex(), and G_SoundIndex().

Referenced by NPC_SpawnType(), and SP_NPC_Droid_Remote().

00018 {
00019         G_SoundIndex("sound/chars/remote/misc/fire.wav");
00020         G_SoundIndex( "sound/chars/remote/misc/hiss.wav");
00021         G_EffectIndex( "env/small_explode");
00022 }

void Remote_Attack void   ) 
 

Definition at line 290 of file NPC_AI_Remote.c.

References entityShared_t::currentOrigin, gNPC_t::desiredYaw, DistanceHorizontalSquared(), gentity_s::enemy, flrand(), MIN_DISTANCE_SQR, NPC, NPC_CheckEnemyExt(), NPC_ClearLOS4(), NPCInfo, Q_irand(), qboolean, qfalse, gentity_s::r, Remote_Hunt(), Remote_Idle(), Remote_MaintainHeight(), Remote_Ranged(), SCF_CHASE_ENEMIES, gNPC_t::scriptFlags, TIMER_Done(), and TIMER_Set().

Referenced by NPC_BSRemote_Default().

00291 {
00292         float           distance;
00293         qboolean        visible;
00294         float           idealDist;
00295         qboolean        advance;
00296         qboolean        retreat;
00297 
00298         if ( TIMER_Done(NPC,"spin") )
00299         {
00300                 TIMER_Set( NPC, "spin", Q_irand( 250, 1500 ) );
00301                 NPCInfo->desiredYaw += Q_irand( -200, 200 ); 
00302         }
00303         // Always keep a good height off the ground
00304         Remote_MaintainHeight();
00305 
00306         // If we don't have an enemy, just idle
00307         if ( NPC_CheckEnemyExt(qfalse) == qfalse )
00308         {
00309                 Remote_Idle();
00310                 return;
00311         }
00312 
00313         // Rate our distance to the target, and our visibilty
00314         distance        = (int) DistanceHorizontalSquared( NPC->r.currentOrigin, NPC->enemy->r.currentOrigin ); 
00315         visible         = NPC_ClearLOS4( NPC->enemy );
00316         idealDist       = MIN_DISTANCE_SQR+(MIN_DISTANCE_SQR*flrand( 0, 1 ));
00317         advance         = (qboolean)(distance > idealDist*1.25);
00318         retreat         = (qboolean)(distance < idealDist*0.75);
00319 
00320         // If we cannot see our target, move to see it
00321         if ( visible == qfalse )
00322         {
00323                 if ( NPCInfo->scriptFlags & SCF_CHASE_ENEMIES )
00324                 {
00325                         Remote_Hunt( visible, advance, retreat );
00326                         return;
00327                 }
00328         }
00329 
00330         Remote_Ranged( visible, advance, retreat );
00331 
00332 }

void Remote_Fire void   ) 
 

Definition at line 229 of file NPC_AI_Remote.c.

References AngleVectors(), CalcEntitySpot(), gentity_s::classname, gentity_s::clipmask, CONTENTS_LIGHTSABER, CreateMissile(), entityShared_t::currentOrigin, gentity_s::damage, DAMAGE_DEATH_KNOCKBACK, gentity_s::dflags, gentity_s::enemy, G_EffectIndex(), G_PlayEffectID(), gentity_t, MASK_SHOT, gentity_s::methodOfDeath, MOD_BRYAR_PISTOL, NPC, qfalse, gentity_s::r, gentity_s::s, SPOT_HEAD, vec3_t, vectoangles(), VectorCopy, VectorSubtract, entityState_s::weapon, and WP_BRYAR_PISTOL.

Referenced by Remote_Ranged().

00230 {
00231         vec3_t  delta1, enemy_org1, muzzle1;
00232         vec3_t  angleToEnemy1;
00233         static  vec3_t  forward, vright, up;
00234         static  vec3_t  muzzle;
00235         gentity_t       *missile;
00236 
00237         CalcEntitySpot( NPC->enemy, SPOT_HEAD, enemy_org1 );
00238         VectorCopy( NPC->r.currentOrigin, muzzle1 );
00239         
00240         VectorSubtract (enemy_org1, muzzle1, delta1);
00241 
00242         vectoangles ( delta1, angleToEnemy1 );
00243         AngleVectors (angleToEnemy1, forward, vright, up);
00244 
00245         missile = CreateMissile( NPC->r.currentOrigin, forward, 1000, 10000, NPC, qfalse );
00246 
00247         G_PlayEffectID( G_EffectIndex("bryar/muzzle_flash"), NPC->r.currentOrigin, forward );
00248 
00249         missile->classname = "briar";
00250         missile->s.weapon = WP_BRYAR_PISTOL;
00251 
00252         missile->damage = 10;
00253         missile->dflags = DAMAGE_DEATH_KNOCKBACK;
00254         missile->methodOfDeath = MOD_BRYAR_PISTOL;
00255         missile->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER;
00256 
00257 }

void Remote_Hunt qboolean  visible,
qboolean  advance,
qboolean  retreat
 

Definition at line 178 of file NPC_AI_Remote.c.

References gentity_s::client, entityShared_t::currentOrigin, gentity_s::enemy, g_spskill, gNPC_t::goalEntity, gNPC_t::goalRadius, vmCvar_t::integer, level, NPC, NPC_GetMoveDirection(), NPCInfo, gclient_s::ps, qfalse, qtrue, gentity_s::r, REMOTE_FORWARD_BASE_SPEED, REMOTE_FORWARD_MULTIPLIER, Remote_Strafe(), gNPC_t::standTime, level_locals_t::time, vec3_t, VectorMA, VectorNormalize(), VectorSubtract, and playerState_s::velocity.

Referenced by Remote_Attack(), and Remote_Ranged().

00179 {
00180         float   distance, speed;
00181         vec3_t  forward;
00182 
00183         //If we're not supposed to stand still, pursue the player
00184         if ( NPCInfo->standTime < level.time )
00185         {
00186                 // Only strafe when we can see the player
00187                 if ( visible )
00188                 {
00189                         Remote_Strafe();
00190                         return;
00191                 }
00192         }
00193 
00194         //If we don't want to advance, stop here
00195         if ( advance == qfalse && visible == qtrue )
00196                 return;
00197 
00198         //Only try and navigate if the player is visible
00199         if ( visible == qfalse )
00200         {
00201                 // Move towards our goal
00202                 NPCInfo->goalEntity = NPC->enemy;
00203                 NPCInfo->goalRadius = 12;
00204 
00205                 //Get our direction from the navigator if we can't see our target
00206                 if ( NPC_GetMoveDirection( forward, &distance ) == qfalse )
00207                         return;
00208         }
00209         else
00210         {
00211                 VectorSubtract( NPC->enemy->r.currentOrigin, NPC->r.currentOrigin, forward );
00212                 distance = VectorNormalize( forward );
00213         }
00214 
00215         speed = REMOTE_FORWARD_BASE_SPEED + REMOTE_FORWARD_MULTIPLIER * g_spskill.integer;
00216         if ( retreat == qtrue )
00217         {
00218                 speed *= -1;
00219         }
00220         VectorMA( NPC->client->ps.velocity, speed, forward, NPC->client->ps.velocity );
00221 }

void Remote_Idle void   ) 
 

Definition at line 339 of file NPC_AI_Remote.c.

References NPC_BSIdle(), and Remote_MaintainHeight().

Referenced by NPC_BSRemote_Default(), and Remote_Attack().

00340 {
00341         Remote_MaintainHeight();
00342 
00343         NPC_BSIdle();
00344 }

void Remote_MaintainHeight void   ) 
 

Definition at line 44 of file NPC_AI_Remote.c.

References CHAN_AUTO, gentity_s::client, entityShared_t::currentOrigin, gentity_s::enemy, fabs(), G_Sound(), G_SoundIndex(), gentity_t, gNPC_t::goalEntity, gNPC_t::lastGoalEntity, entityShared_t::maxs, NPC, NPC_UpdateAngles(), NPCInfo, NULL, gclient_s::ps, Q_irand(), qtrue, gentity_s::r, TIMER_Done(), TIMER_Set(), playerState_s::velocity, and VELOCITY_DECAY.

Referenced by Remote_Attack(), Remote_Idle(), and Remote_Patrol().

00045 {       
00046         float   dif;
00047 
00048         // Update our angles regardless
00049         NPC_UpdateAngles( qtrue, qtrue );
00050 
00051         if ( NPC->client->ps.velocity[2] )
00052         {
00053                 NPC->client->ps.velocity[2] *= VELOCITY_DECAY;
00054 
00055                 if ( fabs( NPC->client->ps.velocity[2] ) < 2 )
00056                 {
00057                         NPC->client->ps.velocity[2] = 0;
00058                 }
00059         }
00060         // If we have an enemy, we should try to hover at or a little below enemy eye level
00061         if ( NPC->enemy )
00062         {
00063                 if (TIMER_Done( NPC, "heightChange"))
00064                 {
00065                         TIMER_Set( NPC,"heightChange",Q_irand( 1000, 3000 ));
00066 
00067                         // Find the height difference
00068                         dif = (NPC->enemy->r.currentOrigin[2] +  Q_irand( 0, NPC->enemy->r.maxs[2]+8 )) - NPC->r.currentOrigin[2]; 
00069 
00070                         // cap to prevent dramatic height shifts
00071                         if ( fabs( dif ) > 2 )
00072                         {
00073                                 if ( fabs( dif ) > 24 )
00074                                 {
00075                                         dif = ( dif < 0 ? -24 : 24 );
00076                                 }
00077                                 dif *= 10;
00078                                 NPC->client->ps.velocity[2] = (NPC->client->ps.velocity[2]+dif)/2;
00079                         //      NPC->fx_time = level.time;
00080                                 G_Sound( NPC, CHAN_AUTO, G_SoundIndex("sound/chars/remote/misc/hiss.wav"));
00081                         }
00082                 }
00083         }
00084         else
00085         {
00086                 gentity_t *goal = NULL;
00087 
00088                 if ( NPCInfo->goalEntity )      // Is there a goal?
00089                 {
00090                         goal = NPCInfo->goalEntity;
00091                 }
00092                 else
00093                 {
00094                         goal = NPCInfo->lastGoalEntity;
00095                 }
00096                 if ( goal )
00097                 {
00098                         dif = goal->r.currentOrigin[2] - NPC->r.currentOrigin[2];
00099 
00100                         if ( fabs( dif ) > 24 )
00101                         {
00102                                 dif = ( dif < 0 ? -24 : 24 );
00103                                 NPC->client->ps.velocity[2] = (NPC->client->ps.velocity[2]+dif)/2;
00104                         }
00105                 }
00106         }
00107 
00108         // Apply friction
00109         if ( NPC->client->ps.velocity[0] )
00110         {
00111                 NPC->client->ps.velocity[0] *= VELOCITY_DECAY;
00112 
00113                 if ( fabs( NPC->client->ps.velocity[0] ) < 1 )
00114                 {
00115                         NPC->client->ps.velocity[0] = 0;
00116                 }
00117         }
00118 
00119         if ( NPC->client->ps.velocity[1] )
00120         {
00121                 NPC->client->ps.velocity[1] *= VELOCITY_DECAY;
00122 
00123                 if ( fabs( NPC->client->ps.velocity[1] ) < 1 )
00124                 {
00125                         NPC->client->ps.velocity[1] = 0;
00126                 }
00127         }
00128 }

void Remote_Patrol void   ) 
 

Definition at line 351 of file NPC_AI_Remote.c.

References BUTTON_WALKING, usercmd_s::buttons, gentity_s::enemy, NPC, NPC_MoveToGoal(), NPC_UpdateAngles(), qtrue, Remote_MaintainHeight(), ucmd, and UpdateGoal().

Referenced by NPC_BSRemote_Default().

00352 {
00353         Remote_MaintainHeight();
00354 
00355         //If we have somewhere to go, then do that
00356         if (!NPC->enemy)
00357         {
00358                 if ( UpdateGoal() )
00359                 {
00360                         //start loop sound once we move
00361                         ucmd.buttons |= BUTTON_WALKING;
00362                         NPC_MoveToGoal( qtrue );
00363                 }
00364         }
00365 
00366         NPC_UpdateAngles( qtrue, qtrue );
00367 }

void Remote_Ranged qboolean  visible,
qboolean  advance,
qboolean  retreat
 

Definition at line 264 of file NPC_AI_Remote.c.

References NPC, NPCInfo, Q_irand(), Remote_Fire(), Remote_Hunt(), SCF_CHASE_ENEMIES, gNPC_t::scriptFlags, TIMER_Done(), and TIMER_Set().

Referenced by Remote_Attack().

00265 {
00266 
00267         if ( TIMER_Done( NPC, "attackDelay" ) ) // Attack?
00268         {
00269                 TIMER_Set( NPC, "attackDelay", Q_irand( 500, 3000 ) );
00270                 Remote_Fire();
00271         }
00272 
00273         if ( NPCInfo->scriptFlags & SCF_CHASE_ENEMIES )
00274         {
00275                 Remote_Hunt( visible, advance, retreat );
00276         }
00277 }

void Remote_Strafe void   ) 
 

Definition at line 139 of file NPC_AI_Remote.c.

References AngleVectors(), CHAN_AUTO, gentity_s::client, entityShared_t::currentOrigin, renderInfo_s::eyeAngles, trace_t::fraction, G_Sound(), G_SoundIndex(), level, MASK_SOLID, NPC, NPCInfo, NULL, entityState_s::number, gclient_s::ps, gentity_s::r, rand(), random, REMOTE_STRAFE_DIS, REMOTE_STRAFE_VEL, REMOTE_UPWARD_PUSH, gclient_s::renderInfo, gentity_s::s, gNPC_t::standTime, level_locals_t::time, trap_Trace(), vec3_t, VectorMA, and playerState_s::velocity.

Referenced by NPC_Remote_Pain(), and Remote_Hunt().

00140 {
00141         int             dir;
00142         vec3_t  end, right;
00143         trace_t tr;
00144 
00145         AngleVectors( NPC->client->renderInfo.eyeAngles, NULL, right, NULL );
00146 
00147         // Pick a random strafe direction, then check to see if doing a strafe would be
00148         //      reasonable valid
00149         dir = ( rand() & 1 ) ? -1 : 1;
00150         VectorMA( NPC->r.currentOrigin, REMOTE_STRAFE_DIS * dir, right, end );
00151 
00152         trap_Trace( &tr, NPC->r.currentOrigin, NULL, NULL, end, NPC->s.number, MASK_SOLID );
00153 
00154         // Close enough
00155         if ( tr.fraction > 0.9f )
00156         {
00157                 VectorMA( NPC->client->ps.velocity, REMOTE_STRAFE_VEL * dir, right, NPC->client->ps.velocity );
00158 
00159                 G_Sound( NPC, CHAN_AUTO, G_SoundIndex("sound/chars/remote/misc/hiss.wav"));
00160 
00161                 // Add a slight upward push
00162                 NPC->client->ps.velocity[2] += REMOTE_UPWARD_PUSH;
00163 
00164                 // Set the strafe start time so we can do a controlled roll
00165         //      NPC->fx_time = level.time;
00166                 NPCInfo->standTime = level.time + 3000 + random() * 500;
00167         }
00168 }