codemp/game/NPC_AI_Howler.c File Reference

#include "b_local.h"

Go to the source code of this file.

Defines

#define MIN_DISTANCE   54
#define MIN_DISTANCE_SQR   ( MIN_DISTANCE * MIN_DISTANCE )
#define MAX_DISTANCE   128
#define MAX_DISTANCE_SQR   ( MAX_DISTANCE * MAX_DISTANCE )
#define LSTATE_CLEAR   0
#define LSTATE_WAITING   1

Functions

void NPC_Howler_Precache (void)
void Howler_Idle (void)
void Howler_Patrol (void)
void Howler_Move (qboolean visible)
void Howler_TryDamage (gentity_t *enemy, int damage)
void Howler_Attack (void)
void Howler_Combat (void)
void NPC_Howler_Pain (gentity_t *self, gentity_t *attacker, int damage)
void NPC_BSHowler_Default (void)


Define Documentation

#define LSTATE_CLEAR   0
 

Definition at line 10 of file NPC_AI_Howler.c.

Referenced by Howler_Combat(), Howler_Patrol(), MineMonster_Combat(), MineMonster_Patrol(), Rancor_Combat(), Rancor_Idle(), Rancor_Patrol(), Wampa_Combat(), Wampa_Idle(), and Wampa_Patrol().

#define LSTATE_WAITING   1
 

Definition at line 11 of file NPC_AI_Howler.c.

Referenced by Howler_Combat(), Howler_Move(), MineMonster_Combat(), MineMonster_Move(), NPC_Howler_Pain(), NPC_MineMonster_Pain(), NPC_Rancor_Pain(), NPC_Wampa_Pain(), Rancor_Move(), Wampa_Combat(), and Wampa_Move().

#define MAX_DISTANCE   128
 

Definition at line 7 of file NPC_AI_Howler.c.

Referenced by Howler_Combat(), Howler_Move(), MineMonster_Combat(), MineMonster_Move(), Rancor_Move(), Wampa_Combat(), and Wampa_Move().

#define MAX_DISTANCE_SQR   ( MAX_DISTANCE * MAX_DISTANCE )
 

Definition at line 8 of file NPC_AI_Howler.c.

#define MIN_DISTANCE   54
 

Definition at line 4 of file NPC_AI_Howler.c.

#define MIN_DISTANCE_SQR   ( MIN_DISTANCE * MIN_DISTANCE )
 

Definition at line 5 of file NPC_AI_Howler.c.


Function Documentation

void Howler_Attack void   ) 
 

Definition at line 112 of file NPC_AI_Howler.c.

References BOTH_ATTACK1, gentity_s::enemy, Howler_TryDamage(), NPC, NPC_SetAnim(), qtrue, random, SETANIM_BOTH, SETANIM_FLAG_HOLD, SETANIM_FLAG_OVERRIDE, TIMER_Done2(), TIMER_Exists(), and TIMER_Set().

Referenced by Howler_Combat().

00113 {
00114         if ( !TIMER_Exists( NPC, "attacking" ))
00115         {
00116                 // Going to do ATTACK1
00117                 TIMER_Set( NPC, "attacking", 1700 + random() * 200 );
00118                 NPC_SetAnim( NPC, SETANIM_BOTH, BOTH_ATTACK1, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD );
00119 
00120                 TIMER_Set( NPC, "attack_dmg", 200 ); // level two damage
00121         }
00122 
00123         // Need to do delayed damage since the attack animations encapsulate multiple mini-attacks
00124         if ( TIMER_Done2( NPC, "attack_dmg", qtrue ))
00125         {
00126                 Howler_TryDamage( NPC->enemy, 5 );
00127         }
00128 
00129         // Just using this to remove the attacking flag at the right time
00130         TIMER_Done2( NPC, "attacking", qtrue );
00131 }

void Howler_Combat void   ) 
 

Definition at line 134 of file NPC_AI_Howler.c.

References gNPC_t::combatMove, entityShared_t::currentOrigin, DistanceHorizontalSquared(), gentity_s::enemy, gNPC_t::goalEntity, gNPC_t::goalRadius, Howler_Attack(), Howler_Move(), gNPC_t::localState, LSTATE_CLEAR, LSTATE_WAITING, MAX_DISTANCE, MIN_DISTANCE_SQR, NPC, NPC_ClearLOS4(), NPC_FaceEnemy(), NPC_MoveToGoal(), NPCInfo, qboolean, qfalse, qtrue, gentity_s::r, TIMER_Done(), TIMER_Done2(), and UpdateGoal().

Referenced by NPC_BSHowler_Default().

00135 {
00136         float distance;
00137         qboolean advance;
00138 
00139         // If we cannot see our target or we have somewhere to go, then do that
00140         if ( !NPC_ClearLOS4( NPC->enemy ) || UpdateGoal( ))
00141         {
00142                 NPCInfo->combatMove = qtrue;
00143                 NPCInfo->goalEntity = NPC->enemy;
00144                 NPCInfo->goalRadius = MAX_DISTANCE;     // just get us within combat range
00145 
00146                 NPC_MoveToGoal( qtrue );
00147                 return;
00148         }
00149 
00150         // Sometimes I have problems with facing the enemy I'm attacking, so force the issue so I don't look dumb
00151         NPC_FaceEnemy( qtrue );
00152 
00153         distance        = DistanceHorizontalSquared( NPC->r.currentOrigin, NPC->enemy->r.currentOrigin );       
00154         advance = (qboolean)( distance > MIN_DISTANCE_SQR ? qtrue : qfalse  );
00155 
00156         if (( advance || NPCInfo->localState == LSTATE_WAITING ) && TIMER_Done( NPC, "attacking" )) // waiting monsters can't attack
00157         {
00158                 if ( TIMER_Done2( NPC, "takingPain", qtrue ))
00159                 {
00160                         NPCInfo->localState = LSTATE_CLEAR;
00161                 }
00162                 else
00163                 {
00164                         Howler_Move( 1 );
00165                 }
00166         }
00167         else
00168         {
00169                 Howler_Attack();
00170         }
00171 }

void Howler_Idle void   ) 
 

Definition at line 28 of file NPC_AI_Howler.c.

Referenced by Howler_Patrol(), and NPC_BSHowler_Default().

00029 {
00030 }

void Howler_Move qboolean  visible  ) 
 

Definition at line 78 of file NPC_AI_Howler.c.

References gentity_s::enemy, gNPC_t::goalEntity, gNPC_t::goalRadius, gNPC_t::localState, LSTATE_WAITING, MAX_DISTANCE, NPC, NPC_MoveToGoal(), NPCInfo, and qtrue.

Referenced by Howler_Combat().

00079 {
00080         if ( NPCInfo->localState != LSTATE_WAITING )
00081         {
00082                 NPCInfo->goalEntity = NPC->enemy;
00083                 NPC_MoveToGoal( qtrue );
00084                 NPCInfo->goalRadius = MAX_DISTANCE;     // just get us within combat range
00085         }
00086 }

void Howler_Patrol void   ) 
 

Definition at line 38 of file NPC_AI_Howler.c.

References BUTTON_WALKING, usercmd_s::buttons, crandom, entityShared_t::currentOrigin, g_entities, G_SetEnemy(), Howler_Idle(), gNPC_t::localState, LSTATE_CLEAR, NPC, NPC_CheckEnemyExt(), NPC_MoveToGoal(), NPCInfo, qfalse, qtrue, gentity_s::r, TIMER_Done(), TIMER_Set(), ucmd, UpdateGoal(), vec3_t, and VectorSubtract.

Referenced by NPC_BSHowler_Default().

00039 {
00040         vec3_t dif;
00041 
00042         NPCInfo->localState = LSTATE_CLEAR;
00043 
00044         //If we have somewhere to go, then do that
00045         if ( UpdateGoal() )
00046         {
00047                 ucmd.buttons &= ~BUTTON_WALKING;
00048                 NPC_MoveToGoal( qtrue );
00049         }
00050         else
00051         {
00052                 if ( TIMER_Done( NPC, "patrolTime" ))
00053                 {
00054                         TIMER_Set( NPC, "patrolTime", crandom() * 5000 + 5000 );
00055                 }
00056         }
00057 
00058         //rwwFIXMEFIXME: Care about all clients, not just client 0
00059         VectorSubtract( g_entities[0].r.currentOrigin, NPC->r.currentOrigin, dif );
00060 
00061         if ( VectorLengthSquared( dif ) < 256 * 256 )
00062         {
00063                 G_SetEnemy( NPC, &g_entities[0] );
00064         }
00065 
00066         if ( NPC_CheckEnemyExt( qtrue ) == qfalse )
00067         {
00068                 Howler_Idle();
00069                 return;
00070         }
00071 }

void Howler_TryDamage gentity_t enemy,
int  damage
 

Definition at line 89 of file NPC_AI_Howler.c.

References AngleVectors(), gentity_s::client, entityShared_t::currentOrigin, DAMAGE_NO_KNOCKBACK, trace_t::endpos, trace_t::entityNum, ENTITYNUM_WORLD, G_Damage(), g_entities, gentity_t, MASK_SHOT, MIN_DISTANCE, MOD_MELEE, NPC, NULL, entityState_s::number, gclient_s::ps, gentity_s::r, gentity_s::s, trap_Trace(), vec3_origin, vec3_t, VectorMA, and playerState_s::viewangles.

Referenced by Howler_Attack().

00090 {
00091         vec3_t  end, dir;
00092         trace_t tr;
00093 
00094         if ( !enemy )
00095         {
00096                 return;
00097         }
00098 
00099         AngleVectors( NPC->client->ps.viewangles, dir, NULL, NULL );
00100         VectorMA( NPC->r.currentOrigin, MIN_DISTANCE, dir, end );
00101 
00102         // Should probably trace from the mouth, but, ah well.
00103         trap_Trace( &tr, NPC->r.currentOrigin, vec3_origin, vec3_origin, end, NPC->s.number, MASK_SHOT );
00104 
00105         if ( tr.entityNum != ENTITYNUM_WORLD )
00106         {
00107                 G_Damage( &g_entities[tr.entityNum], NPC, NPC, dir, tr.endpos, damage, DAMAGE_NO_KNOCKBACK, MOD_MELEE );
00108         }
00109 }

void NPC_BSHowler_Default void   ) 
 

Definition at line 202 of file NPC_AI_Howler.c.

References gentity_s::enemy, Howler_Combat(), Howler_Idle(), Howler_Patrol(), NPC, NPC_UpdateAngles(), NPCInfo, qtrue, SCF_LOOK_FOR_ENEMIES, and gNPC_t::scriptFlags.

Referenced by NPC_BehaviorSet_Howler().

00203 {
00204         if ( NPC->enemy )
00205         {
00206                 Howler_Combat();
00207         }
00208         else if ( NPCInfo->scriptFlags & SCF_LOOK_FOR_ENEMIES )
00209         {
00210                 Howler_Patrol();
00211         }
00212         else
00213         {
00214                 Howler_Idle();
00215         }
00216 
00217         NPC_UpdateAngles( qtrue, qtrue );
00218 }

void NPC_Howler_Pain gentity_t self,
gentity_t attacker,
int  damage
 

Definition at line 178 of file NPC_AI_Howler.c.

References entityState_s::angles, BOTH_PAIN1, gentity_t, gNPC_t::lastPathAngles, gNPC_t::localState, LSTATE_WAITING, gentity_s::NPC, NPC_SetAnim(), gentity_s::s, SETANIM_BOTH, SETANIM_FLAG_HOLD, SETANIM_FLAG_OVERRIDE, TIMER_Remove(), TIMER_Set(), and VectorCopy.

Referenced by NPC_PainFunc().

00179 {
00180         if ( damage >= 10 )
00181         {
00182                 TIMER_Remove( self, "attacking" );
00183                 TIMER_Set( self, "takingPain", 2900 );
00184 
00185                 VectorCopy( self->NPC->lastPathAngles, self->s.angles );
00186 
00187                 NPC_SetAnim( self, SETANIM_BOTH, BOTH_PAIN1, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD );
00188 
00189                 if ( self->NPC )
00190                 {
00191                         self->NPC->localState = LSTATE_WAITING;
00192                 }
00193         }
00194 }

void NPC_Howler_Precache void   ) 
 

Definition at line 18 of file NPC_AI_Howler.c.

Referenced by NPC_SpawnType().

00019 {
00020 }