/* ------------------------- NPC_CheckSoundEvents ------------------------- */ static int G_CheckSoundEvents( gentity_t *self, float maxHearDist, int ignoreAlert, qboolean mustHaveOwner, int minAlertLevel ) { int bestEvent = -1; int bestAlert = -1; int bestTime = -1; int i; float dist, radius; maxHearDist *= maxHearDist; for ( i = 0; i < level.numAlertEvents; i++ ) { //are we purposely ignoring this alert? if ( i == ignoreAlert ) continue; //We're only concerned about sounds if ( level.alertEvents[i].type != AET_SOUND ) continue; //must be at least this noticable if ( level.alertEvents[i].level < minAlertLevel ) continue; //must have an owner? if ( mustHaveOwner && !level.alertEvents[i].owner ) continue; //Must be within range dist = DistanceSquared( level.alertEvents[i].position, self->r.currentOrigin ); //can't hear it if ( dist > maxHearDist ) continue; radius = level.alertEvents[i].radius * level.alertEvents[i].radius; if ( dist > radius ) continue; if ( level.alertEvents[i].addLight ) {//a quiet sound, must have LOS to hear it if ( G_ClearLOS5( self, level.alertEvents[i].position ) == qfalse ) {//no LOS, didn't hear it continue; } } //See if this one takes precedence over the previous one if ( level.alertEvents[i].level >= bestAlert //higher alert level || (level.alertEvents[i].level==bestAlert&&level.alertEvents[i].timestamp >= bestTime) )//same alert level, but this one is newer {//NOTE: equal is better because it's later in the array bestEvent = i; bestAlert = level.alertEvents[i].level; bestTime = level.alertEvents[i].timestamp; } } return bestEvent; }
/* ------------------------- NPC_CheckSightEvents ------------------------- */ static int G_CheckSightEvents( gentity_t *self, int hFOV, int vFOV, float maxSeeDist, int ignoreAlert, qboolean mustHaveOwner, int minAlertLevel ) { int bestEvent = -1; int bestAlert = -1; int bestTime = -1; int i; float dist, radius; maxSeeDist *= maxSeeDist; for ( i = 0; i < level.numAlertEvents; i++ ) { //are we purposely ignoring this alert? if ( i == ignoreAlert ) continue; //We're only concerned about sounds if ( level.alertEvents[i].type != AET_SIGHT ) continue; //must be at least this noticable if ( level.alertEvents[i].level < minAlertLevel ) continue; //must have an owner? if ( mustHaveOwner && !level.alertEvents[i].owner ) continue; //Must be within range dist = DistanceSquared( level.alertEvents[i].position, self->r.currentOrigin ); //can't see it if ( dist > maxSeeDist ) continue; radius = level.alertEvents[i].radius * level.alertEvents[i].radius; if ( dist > radius ) continue; //Must be visible if ( InFOV2( level.alertEvents[i].position, self, hFOV, vFOV ) == qfalse ) continue; if ( G_ClearLOS5( self, level.alertEvents[i].position ) == qfalse ) continue; //FIXME: possibly have the light level at this point affect the // visibility/alert level of this event? Would also // need to take into account how bright the event // itself is. A lightsaber would stand out more // in the dark... maybe pass in a light level that // is added to the actual light level at this position? //See if this one takes precedence over the previous one if ( level.alertEvents[i].level >= bestAlert //higher alert level || (level.alertEvents[i].level==bestAlert&&level.alertEvents[i].timestamp >= bestTime) )//same alert level, but this one is newer {//NOTE: equal is better because it's later in the array bestEvent = i; bestAlert = level.alertEvents[i].level; bestTime = level.alertEvents[i].timestamp; } } return bestEvent; }
qboolean NPC_ClearLOS5( const vec3_t end ) { return G_ClearLOS5( NPC, end ); }