示例#1
0
//NPC's eyes to entity
qboolean G_ClearLOS4( gentity_t *self, gentity_t *ent ) 
{
	vec3_t	eyes;

	//Calculate my position
	CalcEntitySpot( self, SPOT_HEAD_LEAN, eyes );
	
	return G_ClearLOS3( self, eyes, ent );
}
示例#2
0
//ported from SP
void G_DynamicMusicUpdate( void )
{
	int			battle = 0;
	vec3_t		center;
	qboolean	clearLOS = qfalse;
	int			distSq, radius = 2048;
	int			i, e, x;
	gentity_t	*ent;
	int entityList[MAX_GENTITIES];
	int			entTeam;
	vec3_t		mins, maxs;
	int			numListedEntities;
	gentity_t	*player;

	if( DMSData.dmDebounceTime >= 0 && DMSData.dmDebounceTime < level.time )
	{//debounce over, reset to default music
		DMSData.dmDebounceTime = -1;
		DMSData.dmState = DM_AUTO;
		DMSData.olddmState = DM_AUTO;
	}

	if ( DMSData.dmState == DM_DEATH)
	{//Play the death music
		if(DMSData.olddmState != DM_DEATH)
		{//haven't set the state yet
			trap_SetConfigstring( CS_MUSIC, DMS_DEATH_MUSIC );
			DMSData.olddmState = DM_DEATH;
			DMSData.dmDebounceTime = level.time + DMS_DEATH_MUSIC_TIME;
		}
		return;
	}

	if ( DMSData.dmState == DM_BOSS )
	{
		if(DMSData.olddmState != DM_BOSS)
		{
			trap_SetConfigstring( CS_MUSIC, DMSData.bossMusic.fileName );
			DMSData.olddmState = DM_BOSS;
		}
		return;
	}

	if ( DMSData.dmState == DM_SILENCE )
	{//turn off the music
		if(DMSData.olddmState != DM_SILENCE)
		{
			trap_SetConfigstring( CS_MUSIC, "" );
			DMSData.olddmState = DM_SILENCE;
		}
		return;
	}

	if ( DMSData.dmBeatTime > level.time )
	{//not on a beat
		return;
	}

	DMSData.dmBeatTime = level.time + 1000;//1 second beats

	for(i = 0; i < MAX_CLIENTS; i++)
	{
		player = &g_entities[i];

		//check to make sure this player is valid
		if(!player || !player->inuse 
			|| player->client->pers.connected == CON_DISCONNECTED
			|| player->client->sess.sessionTeam == TEAM_SPECTATOR)
		{
			continue;
		}

		//enemy-based
		VectorCopy( player->r.currentOrigin, center );
		for ( x = 0 ; x < 3 ; x++ ) 
		{
			mins[x] = center[x] - radius;
			maxs[x] = center[x] + radius;
		}
	
		numListedEntities = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES );
		for ( e = 0 ; e < numListedEntities ; e++ ) 
		{
			ent = &g_entities[entityList[e]];
			if ( !ent || !ent->inuse )
			{
				continue;
			}

			if ( !ent->client || !ent->NPC )
			{
				if ( ent->classname && (!Q_stricmp( "PAS", ent->classname )||!Q_stricmp( "misc_turret", ent->classname )) )
				{//a turret
					entTeam = ent->teamnodmg;
					//entTeam = ent->noDamageTeam;
				}
				else
				{
					continue;
				}
			}
			else
			{//an NPC
				entTeam = ent->client->playerTeam;
			}

			if ( entTeam == player->client->playerTeam )
			{//ally
				continue;
			}

			if ( entTeam == TEAM_FREE && (!ent->enemy || !ent->enemy->client || ent->enemy->client->playerTeam != player->client->playerTeam) )
			{//a droid that is not mad at me or my allies
				continue;
			}

			if ( !trap_InPVS( player->r.currentOrigin, ent->r.currentOrigin ) )
			{//not potentially visible
				continue;
			}

			if ( ent->client && ent->s.weapon == WP_NONE )
			{//they don't have a weapon... FIXME: only do this for droids?
				continue;
			}

			clearLOS = qfalse;
			if ( (ent->enemy==player&&(!ent->NPC||ent->NPC->confusionTime<level.time)) || (ent->client&&ent->client->ps.weaponTime) || (!ent->client&&ent->attackDebounceTime>level.time))
			{//mad
				if ( ent->health > 0 )
				{//alive
					//FIXME: do I really need this check?
					if ( ent->s.weapon == WP_SABER && ent->client && ent->client->ps.saberHolstered == 2 && ent->enemy != player )
					{//a Jedi who has not yet gotten mad at me
						continue;
					}
					if ( ent->NPC && ent->NPC->behaviorState == BS_CINEMATIC )
					{//they're not actually going to do anything about being mad at me...
						continue;
					}
					//okay, they're in my PVS, but how close are they?  Are they actively attacking me?
					if ( !ent->client && ent->s.weapon == WP_TURRET && ent->fly_sound_debounce_time && ent->fly_sound_debounce_time - level.time < 10000 )
					{//a turret that shot at me less than ten seconds ago
					}
					else if( ent->NPC && level.time < ent->NPC->shotTime )
					{//npc that fired recently
					}
					/* changed from SP
					else if ( ent->client && ent->client->ps.lastShotTime && ent->client->ps.lastShotTime - level.time < 10000 )
					{//an NPC that shot at me less than ten seconds ago
					}
					*/
					else
					{//not actively attacking me lately, see how far away they are
						distSq = DistanceSquared( ent->r.currentOrigin, player->r.currentOrigin );
						if ( distSq > 4194304 )
						{//> 2048 away
							continue;
						}
						else if ( distSq > 1048576 )
						{//> 1024 away
							clearLOS = G_ClearLOS3( player, player->client->renderInfo.eyePoint, ent );
							if ( clearLOS == qfalse )
							{//No LOS
								continue;
							}
						}
					}
					battle++;
				}
			}
		}

		if ( !battle )
		{//no active enemies, but look for missiles, shot impacts, etc...
			//[CoOp]
			int alert = G_CheckAlertEvents( player, qtrue, qtrue, 1024, 1024, -1, qfalse, AEL_SUSPICIOUS, qfalse );
			//int alert = G_CheckAlertEvents( player, qtrue, qtrue, 1024, 1024, -1, qfalse, AEL_SUSPICIOUS );
			//[/CoOp]
			if ( alert != -1 )
			{//FIXME: maybe tripwires and other FIXED things need their own sound, some kind of danger/caution theme
				if ( G_CheckForDanger( player, alert ) )
				{//found danger near by
					battle = 1;
				}
			}
		}
	}

	if ( battle )
	{
		SetDMSState(DM_ACTION);
	}
	else 
	{//switch to explore
		SetDMSState(DM_EXPLORE);
	}

	if(DMSData.dmState != DMSData.olddmState)
	{//switching between action and explore modes
		TransitionBetweenState();
	}
}
示例#3
0
文件: NPC_utils.c 项目: jwginge/ojpa
qboolean NPC_ClearLOS3( const vec3_t start, gentity_t *ent )
{
	return G_ClearLOS3( NPC, start, ent );
}