#include "b_local.h"#include "anims.h"#include "say.h"#include "../icarus/Q3_Interface.h"Go to the source code of this file.
|
|
|
|
|
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
Definition at line 647 of file NPC.c. References client, NPC, NPCInfo, and NULL. Referenced by G_RunFrame().
|
|
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
||||||||||||||||||||
|
Definition at line 16 of file g_nav.c.
00017 {
00018
00019 }
|
|
||||||||||||||||||||
|
|
|
|
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 }
|
|
||||||||||||||||||||
|
Definition at line 11 of file g_nav.c. References vec3_t.
00012 {
00013
00014 }
|
|
||||||||||||||||
|
|
|
|
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
Definition at line 835 of file NPC.c. Referenced by NPC_ExecuteBState().
00836 {
00837 //...
00838 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
Definition at line 1094 of file NPC.c. References NPC_BSRemote_Default(). Referenced by NPC_RunBehavior().
01095 {
01096 NPC_BSRemote_Default();
01097 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
|
|
|
|
|
|
|
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||||||||||
|
|
|
||||||||||||||||
|
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 }
|
|
|
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 }
|
|
||||||||||||||||||||
|
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 }
|
|
|
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 }
|
|
||||||||||||
|
Referenced by CorpsePhysics(), and G_RunObject(). |
|
||||||||||||||||
|
|
|
||||||||||||||||
|
|
|
||||||||||||||||
|
|
|
|
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 }
|
|
|
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 }
|
|
|
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().
|
|
|
Definition at line 627 of file NPC.c. Referenced by RestoreNPCGlobals(), and SaveNPCGlobals(). |
|
|
Definition at line 625 of file NPC.c. Referenced by RestoreNPCGlobals(), and SaveNPCGlobals(). |
|
|
Definition at line 626 of file NPC.c. Referenced by RestoreNPCGlobals(), and SaveNPCGlobals(). |
|
|
Definition at line 628 of file NPC.c. Referenced by RestoreNPCGlobals(), and SaveNPCGlobals(). |
|
|
|
Definition at line 38 of file NPC.c. Referenced by NPC_BSAdvanceFight(), NPC_BSFollowLeader(), NPC_BSHuntAndKill(), NPC_BSShoot(), NPC_CheckCanAttack(), and NPC_CheckPossibleEnemy(). |
|
|
|
|
|
|
|
|
|
Definition at line 658 of file NPC.c. Referenced by NPC_BSJump(). |
|
|
|
|
|
|
|
|
Definition at line 656 of file NPC.c. Referenced by CG_PredictPlayerState(), and NPC_ShowDebugInfo(). |
|
|
|
|
|
|
|
|
|
Definition at line 655 of file NPC.c. Referenced by Cmd_NPC_f(), NPC_BSJump(), and NPC_ShowDebugInfo(). |
|