//-----------------------------------------------------
static qboolean turretG2_find_enemies( gentity_t *self )
//-----------------------------------------------------
{
    qboolean	found = qfalse;
    int			i, count;
    float		bestDist = self->radius * self->radius;
    float		enemyDist;
    vec3_t		enemyDir, org, org2;
    qboolean	foundClient = qfalse;
    gentity_t	*entity_list[MAX_GENTITIES], *target, *bestTarget = NULL;

    if ( self->aimDebounceTime > level.time ) // time since we've been shut off
    {
        // We were active and alert, i.e. had an enemy in the last 3 secs
        if ( self->painDebounceTime < level.time )
        {
            if ( !(self->spawnflags&SPF_TURRETG2_TURBO) )
            {
                G_Sound(self, CHAN_BODY, G_SoundIndex( "sound/chars/turret/ping.wav" ));
            }
            self->painDebounceTime = level.time + 1000;
        }
    }

    VectorCopy( self->r.currentOrigin, org2 );
    if ( self->spawnflags & 2 )
    {
        org2[2] += 20;
    }
    else
    {
        org2[2] -= 20;
    }

    count = G_RadiusList( org2, self->radius, self, qtrue, entity_list );

    for ( i = 0; i < count; i++ )
    {
        trace_t	tr;
        target = entity_list[i];

        if ( !target->client )
        {
            // only attack clients
            if ( !(target->flags&FL_BBRUSH)//not a breakable brush
                    || !target->takedamage//is a bbrush, but invincible
                    || (target->NPC_targetname&&self->targetname&&Q_stricmp(target->NPC_targetname,self->targetname)!=0) )//not in invicible bbrush, but can only be broken by an NPC that is not me
            {
                continue;
            }
            //else: we will shoot at bbrushes!
        }
        if ( target == self || !target->takedamage || target->health <= 0 || ( target->flags & FL_NOTARGET ))
        {
            continue;
        }
        if ( target->client && target->client->sess.sessionTeam == TEAM_SPECTATOR )
        {
            continue;
        }
        if ( self->alliedTeam )
        {
            if ( target->client )
            {
                if ( target->client->sess.sessionTeam == self->alliedTeam )
                {
                    // A bot/client/NPC we don't want to shoot
                    continue;
                }
            }
            else if ( target->teamnodmg == self->alliedTeam )
            {
                // An ent we don't want to shoot
                continue;
            }
        }
        if ( !trap_InPVS( org2, target->r.currentOrigin ))
        {
            continue;
        }

        if ( target->client )
        {
            VectorCopy( target->client->renderInfo.eyePoint, org );
        }
        else
        {
            VectorCopy( target->r.currentOrigin, org );
        }

        if ( self->spawnflags & 2 )
        {
            org[2] -= 15;
        }
        else
        {
            org[2] += 5;
        }

        trap_Trace( &tr, org2, NULL, NULL, org, self->s.number, MASK_SHOT );

        if ( !tr.allsolid && !tr.startsolid && ( tr.fraction == 1.0 || tr.entityNum == target->s.number ))
        {
            // Only acquire if have a clear shot, Is it in range and closer than our best?
            VectorSubtract( target->r.currentOrigin, self->r.currentOrigin, enemyDir );
            enemyDist = VectorLengthSquared( enemyDir );

            if ( enemyDist < bestDist || (target->client && !foundClient))// all things equal, keep current
            {
                if ( self->attackDebounceTime < level.time )
                {
                    // We haven't fired or acquired an enemy in the last 2 seconds-start-up sound
                    if ( !(self->spawnflags&SPF_TURRETG2_TURBO) )
                    {
                        G_Sound( self, CHAN_BODY, G_SoundIndex( "sound/chars/turret/startup.wav" ));
                    }

                    // Wind up turrets for a bit
                    self->attackDebounceTime = level.time + 1400;
                }

                bestTarget = target;
                bestDist = enemyDist;
                found = qtrue;
                if ( target->client )
                {   //prefer clients over non-clients
                    foundClient = qtrue;
                }
            }
        }
    }

    if ( found )
    {
        /*
        if ( !self->enemy )
        {//just aquired one
        	AddSoundEvent( bestTarget, self->r.currentOrigin, 256, AEL_DISCOVERED );
        	AddSightEvent( bestTarget, self->r.currentOrigin, 512, AEL_DISCOVERED, 20 );
        }
        */
        G_SetEnemy( self, bestTarget );
        if ( VALIDSTRING( self->target2 ))
        {
            G_UseTargets2( self, self, self->target2 );
        }
    }

    return found;
}
Beispiel #2
0
//-----------------------------------------------------
static qboolean VEH_TurretFindEnemies( Vehicle_t *pVeh, 
						 gentity_t *parent, 
						 turretStats_t *turretStats, 
						 int turretNum, int curMuzzle )
//-----------------------------------------------------
{
	qboolean	found = qfalse;
	int			i, count;
	float		bestDist = turretStats->fAIRange * turretStats->fAIRange;
	float		enemyDist;
	vec3_t		enemyDir, org, org2;
	qboolean	foundClient = qfalse;
	gentity_t	*entity_list[MAX_GENTITIES], *target, *bestTarget = NULL;

	WP_CalcVehMuzzle( parent, curMuzzle );
	VectorCopy( pVeh->m_vMuzzlePos[curMuzzle], org2 );

	count = G_RadiusList( org2, turretStats->fAIRange, parent, qtrue, entity_list );

	for ( i = 0; i < count; i++ )
	{
		trace_t	tr;
		target = entity_list[i];

		if ( target == parent 
			|| !target->takedamage 
			|| target->health <= 0 
			|| ( target->flags & FL_NOTARGET ))
		{
			continue;
		}
		if ( !target->client )
		{// only attack clients
			if ( !(target->flags&FL_BBRUSH)//not a breakable brush
				|| !target->takedamage//is a bbrush, but invincible
				|| (target->NPC_targetname&&parent->targetname&&Q_stricmp(target->NPC_targetname,parent->targetname)!=0) )//not in invicible bbrush, but can only be broken by an NPC that is not me
			{
				if ( target->s.weapon == WP_TURRET
					&& target->classname
					&& Q_strncmp( "misc_turret", target->classname, 11 ) == 0 )
				{//these guys we want to shoot at
				}
				else
				{
					continue;
				}
			}
			//else: we will shoot at bbrushes!
		}
		else if ( target->client->sess.sessionTeam == TEAM_SPECTATOR )
		{
			continue;
		}
		else if ( target->client->tempSpectate >= level.time )
		{
			continue;
		}
		if ( target == ((gentity_t*)pVeh->m_pPilot)
			|| target->r.ownerNum == parent->s.number )
		{//don't get angry at my pilot or passengers?
			continue;
		}
		if ( parent->client
			&& parent->client->sess.sessionTeam )
		{
			if ( target->client )
			{
				if ( target->client->sess.sessionTeam == parent->client->sess.sessionTeam )
				{ 
					// A bot/client/NPC we don't want to shoot
					continue;
				}
			}
			else if ( target->teamnodmg == parent->client->sess.sessionTeam )
			{//some other entity that's allied with us
				continue;
			}
		}
		if ( !trap->InPVS( org2, target->r.currentOrigin ))
		{
			continue;
		}

		VectorCopy( target->r.currentOrigin, org );

		trap->Trace( &tr, org2, NULL, NULL, org, parent->s.number, MASK_SHOT, qfalse, 0, 0 );

		if ( tr.entityNum == target->s.number
			|| (!tr.allsolid && !tr.startsolid && tr.fraction == 1.0 ) )
		{
			// Only acquire if have a clear shot, Is it in range and closer than our best?
			VectorSubtract( target->r.currentOrigin, org2, enemyDir );
			enemyDist = VectorLengthSquared( enemyDir );

			if ( enemyDist < bestDist || (target->client && !foundClient))// all things equal, keep current
			{
				bestTarget = target;
				bestDist = enemyDist;
				found = qtrue;
				if ( target->client )
				{//prefer clients over non-clients
					foundClient = qtrue;
				}
			}
		}
	}

	if ( found )
	{
		pVeh->turretStatus[turretNum].enemyEntNum = bestTarget->s.number;
	}

	return found;
}
Beispiel #3
0
//-----------------------------------------------------
static qboolean turret_find_enemies( gentity_t *self )
//-----------------------------------------------------
{
	qboolean	found = qfalse;
	int			i, count;
	float		bestDist = self->radius * self->radius;
	float		enemyDist;
	vec3_t		enemyDir, org, org2;
	gentity_t	*entity_list[MAX_GENTITIES], *target, *bestTarget = NULL;
	trace_t		tr;
	gentity_t *top = &g_entities[self->r.ownerNum];
	if ( !top )
	{
		return qfalse;
	}

	if ( self->aimDebounceTime > level.time ) // time since we've been shut off
	{
		// We were active and alert, i.e. had an enemy in the last 3 secs
		if ( self->timestamp < level.time )
		{
			//G_Sound(self, CHAN_BODY, G_SoundIndex( "sound/chars/turret/ping.wav" ));
			self->timestamp = level.time + 1000;
		}
	}

	VectorCopy( top->r.currentOrigin, org2 );

	count = G_RadiusList( org2, self->radius, self, qtrue, entity_list );

	for ( i = 0; i < count; i++ )
	{
		target = entity_list[i];

		if ( !target->client )
		{
			// only attack clients
			continue;
		}
		if ( target == self || !target->takedamage || target->health <= 0 || ( target->flags & FL_NOTARGET ))
		{
			continue;
		}
		if ( target->client->sess.sessionTeam == TEAM_SPECTATOR )
		{
			continue;
		}
		if ( target->client->tempSpectate >= level.time )
		{
			continue;
		}
		if ( self->alliedTeam )
		{
			if ( target->client )
			{
				if ( target->client->sess.sessionTeam == self->alliedTeam )
				{ 
					// A bot/client/NPC we don't want to shoot
					continue;
				}
			}
			else if ( target->teamnodmg == self->alliedTeam )
			{ 
				// An ent we don't want to shoot
				continue;
			}
		}
		if ( !trap->InPVS( org2, target->r.currentOrigin ))
		{
			continue;
		}

		VectorCopy( target->r.currentOrigin, org );
		org[2] += target->r.maxs[2]*0.5f;

		trap->Trace( &tr, org2, NULL, NULL, org, self->s.number, MASK_SHOT, qfalse, 0, 0 );

		if ( !tr.allsolid && !tr.startsolid && ( tr.fraction == 1.0 || tr.entityNum == target->s.number ))
		{
			// Only acquire if have a clear shot, Is it in range and closer than our best?
			VectorSubtract( target->r.currentOrigin, top->r.currentOrigin, enemyDir );
			enemyDist = VectorLengthSquared( enemyDir );

			if ( enemyDist < bestDist // all things equal, keep current
				|| (!Q_stricmp( "atst_vehicle", target->NPC_type ) && bestTarget && Q_stricmp( "atst_vehicle", bestTarget->NPC_type ) ) )//target AT-STs over non-AT-STs... FIXME: must be a better, easier way to tell this, no?
			{
				if ( self->attackDebounceTime < level.time )
				{
					// We haven't fired or acquired an enemy in the last 2 seconds-start-up sound
					//G_Sound( self, CHAN_BODY, G_SoundIndex( "sound/chars/turret/startup.wav" ));

					// Wind up turrets for a bit
					self->attackDebounceTime = level.time + 1400;
				}

				bestTarget = target;
				bestDist = enemyDist;
				found = qtrue;
			}
		}
	}

	if ( found )
	{
		G_SetEnemy( self, bestTarget );
		if ( VALIDSTRING( self->target2 ))
		{
			G_UseTargets2( self, self, self->target2 );
		}
	}

	return found;
}