Ejemplo n.º 1
0
/*
==============
AICast_CheckVisibility
==============
*/
qboolean AICast_CheckVisibility( gentity_t *srcent, gentity_t *destent ) {
	vec3_t dir, entangles, middle, eye, viewangles;
	cast_state_t        *cs, *ocs;
	float fov, dist;
	int viewer, ent;
	cast_visibility_t   *vis;
	orientation_t       or;

	if ( destent->flags & FL_NOTARGET ) {
		return qfalse;
	}
	//
	viewer = srcent->s.number;
	ent = destent->s.number;
	//
	cs = AICast_GetCastState( viewer );
	ocs = AICast_GetCastState( ent );
	//
	vis = &cs->vislist[ent];
	//
	// if the destent is the client, and they have just loaded a savegame, ignore them temporarily
	if ( !destent->aiCharacter && level.lastLoadTime && ( level.lastLoadTime > level.time - 2000 ) && !vis->visible_timestamp ) {
		return qfalse;
	}
	// if we heard them
	/*
	if (	(vis->lastcheck_timestamp) &&
			(ocs->lastWeaponFired) &&
			(ocs->lastWeaponFired >= vis->lastcheck_timestamp) &&
			(AICast_GetWeaponSoundRange( ocs->lastWeaponFiredWeaponNum ) > Distance( srcent->r.currentOrigin, ocs->lastWeaponFiredPos ))) {
		return qtrue;
	}
	*/
	//
	// set the FOV
	fov = cs->attributes[FOV] * aiStateFovScales[cs->aiState];
	if ( !fov ) { // assume it's a player, give them a generic fov
		fov = 180;
	}
	if ( cs->aiFlags & AIFL_ZOOMING ) {
		fov *= 0.8;
	} else {
		if ( cs->lastEnemy >= 0 ) {   // they've already been in a fight, so give them a very large fov
			if ( fov < 270 ) {
				fov = 270;
			}
		}
	}
	// RF, if they were visible last check, then give us a full FOV, since we are aware of them
	if ( cs->aiState >= AISTATE_ALERT && vis->visible_timestamp == vis->lastcheck_timestamp ) {
		fov = 360;
	}
	//calculate middle of bounding box
	VectorAdd( destent->r.mins, destent->r.maxs, middle );
	VectorScale( middle, 0.5, middle );
	VectorAdd( destent->client->ps.origin, middle, middle );
	// calculate eye position
	if ( ( level.lastLoadTime < level.time - 4000 ) && ( srcent->r.svFlags & SVF_CASTAI ) ) {
		if ( clientHeadTagTimes[srcent->s.number] == level.time ) {
			// use the actual direction the head is facing
			vectoangles( clientHeadTags[srcent->s.number].axis[0], viewangles );
			// and the actual position of the head
			VectorCopy( clientHeadTags[srcent->s.number].origin, eye );
		} else if ( trap_GetTag( srcent->s.number, "tag_head", &or ) ) {
			// use the actual direction the head is facing
			vectoangles( or.axis[0], viewangles );
			// and the actual position of the head
			VectorCopy( or.origin, eye );
			VectorMA( eye, 12, or.axis[2], eye );
			// save orientation data
			memcpy( &clientHeadTags[srcent->s.number], &or, sizeof( orientation_t ) );
			clientHeadTagTimes[srcent->s.number] = level.time;
		} else {
			VectorCopy( srcent->client->ps.origin, eye );
			eye[2] += srcent->client->ps.viewheight;
			VectorCopy( srcent->client->ps.viewangles, viewangles );
			// save orientation data (so we dont keep checking for a tag when it doesn't exist)
			VectorCopy( eye, clientHeadTags[srcent->s.number].origin );
			AnglesToAxis( viewangles, clientHeadTags[srcent->s.number].axis );
			clientHeadTagTimes[srcent->s.number] = level.time;
		}
	} else {
		VectorCopy( srcent->client->ps.origin, eye );
		eye[2] += srcent->client->ps.viewheight;
		VectorCopy( srcent->client->ps.viewangles, viewangles );
	}
	//check if entity is within field of vision
	VectorSubtract( middle, eye, dir );
	vectoangles( dir, entangles );
	//
	dist = VectorLength( dir );
	//
	// alertness is visible range
	if ( cs->bs && dist > cs->attributes[ALERTNESS] ) {
		return qfalse;
	}
	// check FOV
	if ( !AICast_InFieldOfVision( viewangles, fov, entangles ) ) {
		return qfalse;
	}
	//
	if ( !AICast_VisibleFromPos( srcent->client->ps.origin, srcent->s.number, destent->client->ps.origin, destent->s.number, qtrue ) ) {
		return qfalse;
	}
	//
	return qtrue;
}
Ejemplo n.º 2
0
/*
==============
AICast_CheckVisibility
==============
*/
qboolean AICast_CheckVisibility( gentity_t *srcent, gentity_t *destent ) {
	vec3_t dir, entangles, middle, eye, viewangles;
	cast_state_t        *cs;
	float fov, dist;
	int viewer, ent;
	orientation_t       or;

	if ( destent->flags & FL_NOTARGET ) {
		return qfalse;
	}

	viewer = srcent->s.number;
	ent = destent->s.number;
	//
	cs = AICast_GetCastState( viewer );
	AICast_GetCastState( ent );

	// set the FOV
	fov = cs->attributes[FOV] * aiStateFovScales[cs->aiState];
	if ( !fov ) { // assume it's a player, give them a generic fov
		fov = 180;
	}
	if ( cs->aiFlags & AIFL_ZOOMING ) {
		fov *= 0.8;
	}
	//calculate middle of bounding box
	VectorAdd( destent->r.mins, destent->r.maxs, middle );
	VectorScale( middle, 0.5, middle );
	VectorAdd( destent->client->ps.origin, middle, middle );
	// calculate eye position
	if ( srcent->r.svFlags & SVF_CASTAI ) {
		if ( trap_GetTag( srcent->s.number, "tag_head", &or ) ) {
			// use the actual direction the head is facing
			vectoangles( or.axis[0], viewangles );
			// and the actual position of the head
			VectorCopy( or.origin, eye );
		} else {
			VectorCopy( srcent->client->ps.origin, eye );
			eye[2] += srcent->client->ps.viewheight;
			VectorCopy( srcent->client->ps.viewangles, viewangles );
		}
	} else {
		VectorCopy( srcent->client->ps.origin, eye );
		eye[2] += srcent->client->ps.viewheight;
		VectorCopy( srcent->client->ps.viewangles, viewangles );
	}
	//check if entity is within field of vision
	VectorSubtract( middle, eye, dir );
	vectoangles( dir, entangles );
	//
	dist = VectorLength( dir );
	//
	// alertness is visible range
	if ( cs->bs && dist > cs->attributes[ALERTNESS] ) {
		return qfalse;
	}
	// check FOV
	if ( !AICast_InFieldOfVision( viewangles, fov, entangles ) ) {
		return qfalse;
	}
	//
	if ( !AICast_VisibleFromPos( srcent->client->ps.origin, srcent->s.number, destent->client->ps.origin, destent->s.number, qtrue ) ) {
		return qfalse;
	}
	//
	return qtrue;
}