Ejemplo n.º 1
0
gentity_t* G_BuildHead(gentity_t *ent) {
	gentity_t* head;
	orientation_t or;			// DHM - Nerve

	head = G_Spawn ();

	if (trap_GetTag( ent->s.number, 0, "tag_head", &or )) {
		G_SetOrigin( head, or.origin );
	} else {
		float height, dest;
		vec3_t v, angles, forward, up, right;

		G_SetOrigin (head, ent->r.currentOrigin); 

		if( ent->client->ps.eFlags & EF_PRONE ) {
			height = ent->client->ps.viewheight - 56;
		} else if( ent->client->ps.pm_flags & PMF_DUCKED ) {	// closer fake offset for 'head' box when crouching
			height = ent->client->ps.crouchViewHeight - 12;
		} else {
			height = ent->client->ps.viewheight;
		}

		// NERVE - SMF - this matches more closely with WolfMP models
		VectorCopy( ent->client->ps.viewangles, angles );
		if ( angles[PITCH] > 180 ) {
			dest = (-360 + angles[PITCH]) * 0.75;
		} else {
			dest = angles[PITCH] * 0.75;
		}
		angles[PITCH] = dest;

		AngleVectors( angles, forward, right, up );
		if( ent->client->ps.eFlags & EF_PRONE ) {
			VectorScale( forward, 24, v );
		} else {
			VectorScale( forward, 5, v );
		}
		VectorMA( v, 18, up, v );

		VectorAdd( v, head->r.currentOrigin, head->r.currentOrigin );
		head->r.currentOrigin[2] += height / 2;
		// -NERVE - SMF
	}

	VectorCopy (head->r.currentOrigin, head->s.origin);
	VectorCopy (ent->r.currentAngles, head->s.angles); 
	VectorCopy (head->s.angles, head->s.apos.trBase);
	VectorCopy (head->s.angles, head->s.apos.trDelta);
	VectorSet (head->r.mins , -6, -6, -2); // JPW NERVE changed this z from -12 to -6 for crouching, also removed standing offset
	VectorSet (head->r.maxs , 6, 6, 10); // changed this z from 0 to 6
	head->clipmask = CONTENTS_SOLID;
	head->r.contents = CONTENTS_SOLID;
	head->parent = ent;
	head->s.eType = ET_TEMPHEAD;

	trap_LinkEntity (head);
	
	return head;
}
Ejemplo n.º 2
0
qboolean IsHeadShot( gentity_t *targ, qboolean isAICharacter, vec3_t dir, vec3_t point, int mod ) {
	gentity_t   *head;
	trace_t tr;
	vec3_t start, end;
	gentity_t   *traceEnt;
	orientation_t orient;           // DHM - Nerve

	qboolean head_shot_weapon = qfalse;

	// not a player or critter so bail
	if ( !( targ->client ) ) {
		return qfalse;
	}

	if ( targ->health <= 0 ) {
		return qfalse;
	}

	head_shot_weapon = IsHeadShotWeapon( mod, isAICharacter );

	if ( head_shot_weapon ) {
		head = G_Spawn();

		if ( trap_GetTag( targ->s.number, "tag_head", &orient ) ) {
			G_SetOrigin( head, orient.origin );
		} else {
			float height, dest;
			vec3_t v, angles, forward, up, right;

			G_SetOrigin( head, targ->r.currentOrigin );

			if ( targ->client->ps.pm_flags & PMF_DUCKED ) { // closer fake offset for 'head' box when crouching
				height = targ->client->ps.crouchViewHeight - 12;
			} else {
				height = targ->client->ps.viewheight;
			}

			// NERVE - SMF - this matches more closely with WolfMP models
			VectorCopy( targ->client->ps.viewangles, angles );
			if ( angles[PITCH] > 180 ) {
				dest = ( -360 + angles[PITCH] ) * 0.75;
			} else {
				dest = angles[PITCH] * 0.75;
			}
			angles[PITCH] = dest;

			AngleVectors( angles, forward, right, up );
			VectorScale( forward, 5, v );
			VectorMA( v, 18, up, v );

			VectorAdd( v, head->r.currentOrigin, head->r.currentOrigin );
			head->r.currentOrigin[2] += height / 2;
			// -NERVE - SMF
		}

		VectorCopy( head->r.currentOrigin, head->s.origin );
		VectorCopy( targ->r.currentAngles, head->s.angles );
		VectorCopy( head->s.angles, head->s.apos.trBase );
		VectorCopy( head->s.angles, head->s.apos.trDelta );
		VectorSet( head->r.mins, -6, -6, -2 ); // JPW NERVE changed this z from -12 to -6 for crouching, also removed standing offset
		VectorSet( head->r.maxs, 6, 6, 10 ); // changed this z from 0 to 6
		head->clipmask = CONTENTS_SOLID;
		head->r.contents = CONTENTS_SOLID;

		trap_LinkEntity( head );

		// trace another shot see if we hit the head
		VectorCopy( point, start );
		VectorMA( start, 64, dir, end );
		trap_Trace( &tr, start, NULL, NULL, end, targ->s.number, MASK_SHOT );

		traceEnt = &g_entities[ tr.entityNum ];

		if ( g_debugBullets.integer >= 3 ) {   // show hit player head bb
			gentity_t *tent;
			vec3_t b1, b2;
			VectorCopy( head->r.currentOrigin, b1 );
			VectorCopy( head->r.currentOrigin, b2 );
			VectorAdd( b1, head->r.mins, b1 );
			VectorAdd( b2, head->r.maxs, b2 );
			tent = G_TempEntity( b1, EV_RAILTRAIL );
			VectorCopy( b2, tent->s.origin2 );
			tent->s.dmgFlags = 1;

			// show headshot trace
			// end the headshot trace at the head box if it hits
			if ( tr.fraction != 1 ) {
				VectorMA( start, ( tr.fraction * 64 ), dir, end );
			}
			tent = G_TempEntity( start, EV_RAILTRAIL );
			VectorCopy( end, tent->s.origin2 );
			tent->s.dmgFlags = 0;
		}

		G_FreeEntity( head );

		if ( traceEnt == head ) {
			level.totalHeadshots++;         // NERVE - SMF
			return qtrue;
		} else {
			level.missedHeadshots++;    // NERVE - SMF
		}
	}

	return qfalse;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
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.º 5
0
/*
==============
IsHeadShot
==============
*/
qboolean IsHeadShot( gentity_t *targ, gentity_t *attacker, vec3_t dir, vec3_t point, int mod ) {
	gentity_t   *head;
	trace_t tr;
	vec3_t start, end;
	gentity_t   *traceEnt;
	orientation_t or;

	qboolean head_shot_weapon = qfalse;

	// not a player or critter so bail
	if ( !( targ->client ) ) {
		return qfalse;
	}

	if ( targ->health <= 0 ) {
		return qfalse;
	}

	head_shot_weapon = IsHeadShotWeapon( mod, targ, attacker );

	if ( head_shot_weapon ) {
		head = G_Spawn();

		G_SetOrigin( head, targ->r.currentOrigin );

		// RF, if there is a valid tag_head for this entity, then use that
		if ( ( targ->r.svFlags & SVF_CASTAI ) && trap_GetTag( targ->s.number, "tag_head", &or ) ) {
			VectorCopy( or.origin, head->r.currentOrigin );
			VectorMA( head->r.currentOrigin, 6, or.axis[2], head->r.currentOrigin );    // tag is at base of neck
		} else if ( targ->client->ps.pm_flags & PMF_DUCKED ) { // closer fake offset for 'head' box when crouching
			head->r.currentOrigin[2] += targ->client->ps.crouchViewHeight + 8; // JPW NERVE 16 is kludge to get head height to match up
		}
		//else if(targ->client->ps.legsAnim == LEGS_IDLE && targ->aiCharacter == AICHAR_SOLDIER)	// standing with legs bent (about a head shorter than other leg poses)
		//	head->r.currentOrigin[2] += targ->client->ps.viewheight;
		else {
			head->r.currentOrigin[2] += targ->client->ps.viewheight; // JPW NERVE pulled this	// 6 is fudged "head height" value

		}
		VectorCopy( head->r.currentOrigin, head->s.origin );
		VectorCopy( targ->r.currentAngles, head->s.angles );
		VectorCopy( head->s.angles, head->s.apos.trBase );
		VectorCopy( head->s.angles, head->s.apos.trDelta );
		VectorSet( head->r.mins, -6, -6, -6 ); // JPW NERVE changed this z from -12 to -6 for crouching, also removed standing offset
		VectorSet( head->r.maxs, 6, 6, 6 ); // changed this z from 0 to 6
		head->clipmask = CONTENTS_SOLID;
		head->r.contents = CONTENTS_SOLID;

		trap_LinkEntity( head );

		// trace another shot see if we hit the head
		VectorCopy( point, start );
		VectorMA( start, 64, dir, end );
		trap_Trace( &tr, start, NULL, NULL, end, targ->s.number, MASK_SHOT );

		traceEnt = &g_entities[ tr.entityNum ];

		if ( g_debugBullets.integer >= 3 ) {   // show hit player head bb
			gentity_t *tent;
			vec3_t b1, b2;
			VectorCopy( head->r.currentOrigin, b1 );
			VectorCopy( head->r.currentOrigin, b2 );
			VectorAdd( b1, head->r.mins, b1 );
			VectorAdd( b2, head->r.maxs, b2 );
			tent = G_TempEntity( b1, EV_RAILTRAIL );
			VectorCopy( b2, tent->s.origin2 );
			tent->s.dmgFlags = 1;

			// show headshot trace
			// end the headshot trace at the head box if it hits
			if ( tr.fraction != 1 ) {
				VectorMA( start, ( tr.fraction * 64 ), dir, end );
			}
			tent = G_TempEntity( start, EV_RAILTRAIL );
			VectorCopy( end, tent->s.origin2 );
			tent->s.dmgFlags = 0;
		}

		G_FreeEntity( head );

		if ( traceEnt == head ) {
			return qtrue;
		}
	}

	return qfalse;
}