//------------------------------------ void Seeker_FollowPlayer( void ) { Seeker_MaintainHeight(); float dis = DistanceHorizontalSquared( NPC->currentOrigin, g_entities[0].currentOrigin ); vec3_t pt, dir; if ( dis < MIN_DISTANCE_SQR ) { // generally circle the player closely till we take an enemy..this is our target point pt[0] = g_entities[0].currentOrigin[0] + cos( level.time * 0.001f + NPC->random ) * 56; pt[1] = g_entities[0].currentOrigin[1] + sin( level.time * 0.001f + NPC->random ) * 56; pt[2] = g_entities[0].currentOrigin[2] + 40; VectorSubtract( pt, NPC->currentOrigin, dir ); VectorMA( NPC->client->ps.velocity, 0.8f, dir, NPC->client->ps.velocity ); } else { if ( TIMER_Done( NPC, "seekerhiss" )) { TIMER_Set( NPC, "seekerhiss", 1000 + random() * 1000 ); G_Sound( NPC, G_SoundIndex( "sound/chars/seeker/misc/hiss" )); } // Hey come back! NPCInfo->goalEntity = &g_entities[0]; NPCInfo->goalRadius = 32; NPC_MoveToGoal( qtrue ); NPC->owner = &g_entities[0]; } if ( NPCInfo->enemyCheckDebounceTime < level.time ) { // check twice a second to find a new enemy Seeker_FindEnemy(); NPCInfo->enemyCheckDebounceTime = level.time + 500; } NPC_UpdateAngles( qtrue, qtrue ); }
//------------------------------------ void Seeker_FollowOwner( void ) { float dis, minDistSqr; vec3_t pt, dir; gentity_t *owner = &g_entities[NPCS.NPC->s.owner]; Seeker_MaintainHeight(); if ( NPCS.NPC->client->NPC_class == CLASS_BOBAFETT ) { owner = NPCS.NPC->enemy; } if ( !owner || owner == NPCS.NPC || !owner->client ) { return; } //rwwFIXMEFIXME: Care about all clients not just 0 dis = DistanceHorizontalSquared( NPCS.NPC->r.currentOrigin, owner->r.currentOrigin ); minDistSqr = MIN_DISTANCE_SQR; if ( NPCS.NPC->client->NPC_class == CLASS_BOBAFETT ) { if ( TIMER_Done( NPCS.NPC, "flameTime" ) ) { minDistSqr = 200*200; } } if ( dis < minDistSqr ) { // generally circle the player closely till we take an enemy..this is our target point if ( NPCS.NPC->client->NPC_class == CLASS_BOBAFETT ) { pt[0] = owner->r.currentOrigin[0] + cos( level.time * 0.001f + NPCS.NPC->random ) * 250; pt[1] = owner->r.currentOrigin[1] + sin( level.time * 0.001f + NPCS.NPC->random ) * 250; if ( NPCS.NPC->client->jetPackTime < level.time ) { pt[2] = NPCS.NPC->r.currentOrigin[2] - 64; } else { pt[2] = owner->r.currentOrigin[2] + 200; } } else { pt[0] = owner->r.currentOrigin[0] + cos( level.time * 0.001f + NPCS.NPC->random ) * 56; pt[1] = owner->r.currentOrigin[1] + sin( level.time * 0.001f + NPCS.NPC->random ) * 56; pt[2] = owner->r.currentOrigin[2] + 40; } VectorSubtract( pt, NPCS.NPC->r.currentOrigin, dir ); VectorMA( NPCS.NPC->client->ps.velocity, 0.8f, dir, NPCS.NPC->client->ps.velocity ); } else { if ( NPCS.NPC->client->NPC_class != CLASS_BOBAFETT ) { if ( TIMER_Done( NPCS.NPC, "seekerhiss" )) { TIMER_Set( NPCS.NPC, "seekerhiss", 1000 + Q_flrand(0.0f, 1.0f) * 1000 ); G_Sound( NPCS.NPC, CHAN_AUTO, G_SoundIndex( "sound/chars/seeker/misc/hiss" )); } } // Hey come back! NPCS.NPCInfo->goalEntity = owner; NPCS.NPCInfo->goalRadius = 32; NPC_MoveToGoal( qtrue ); NPCS.NPC->parent = owner; } if ( NPCS.NPCInfo->enemyCheckDebounceTime < level.time ) { // check twice a second to find a new enemy Seeker_FindEnemy(); NPCS.NPCInfo->enemyCheckDebounceTime = level.time + 500; } NPC_UpdateAngles( qtrue, qtrue ); }
//[CoOp] //------------------------------------ void Seeker_FollowPlayer( void ) { //hover around the closest player //[SeekerItemNpc] #if 1 vec3_t pt, dir; float dis; float minDistSqr = MIN_DISTANCE_SQR; gentity_t *target; Seeker_MaintainHeight(); if(NPC->activator && NPC->activator->client) { if(NPC->activator->client->remote != NPC || NPC->activator->health <= 0) { //have us fall down and explode. NPC->NPC->aiFlags |= NPCAI_CUSTOM_GRAVITY; return; } target = NPCInfo->goalEntity; if(!target) target = NPC->client->leader; } else { target = FindClosestPlayer(NPC->r.currentOrigin, NPC->client->playerTeam); } if(!target) { //in MP it's actually possible that there's no players on our team at the moment. return; } dis = DistanceHorizontalSquared( NPC->r.currentOrigin, target->r.currentOrigin ); if ( NPC->client->NPC_class == CLASS_BOBAFETT ) { if ( TIMER_Done( NPC, "flameTime" ) ) { minDistSqr = 200*200; } } if ( dis < minDistSqr ) { // generally circle the player closely till we take an enemy..this is our target point if ( NPC->client->NPC_class == CLASS_BOBAFETT ) { pt[0] = target->r.currentOrigin[0] + cos( level.time * 0.001f + NPC->random ) * 250; pt[1] = target->r.currentOrigin[1] + sin( level.time * 0.001f + NPC->random ) * 250; if ( NPC->client->jetPackTime < level.time ) { pt[2] = target->r.currentOrigin[2] - 64; } else { pt[2] = target->r.currentOrigin[2] + 200; } } else { pt[0] = target->r.currentOrigin[0] + cos( level.time * 0.001f + NPC->random ) * 56; pt[1] = target->r.currentOrigin[1] + sin( level.time * 0.001f + NPC->random ) * 56; pt[2] = target->r.currentOrigin[2] + 40; } VectorSubtract( pt, NPC->r.currentOrigin, dir ); VectorMA( NPC->client->ps.velocity, 0.8f, dir, NPC->client->ps.velocity ); } else { if ( NPC->client->NPC_class != CLASS_BOBAFETT ) { if ( TIMER_Done( NPC, "seekerhiss" )) { TIMER_Set( NPC, "seekerhiss", 1000 + random() * 1000 ); G_Sound( NPC, CHAN_AUTO, G_SoundIndex( "sound/chars/seeker/misc/hiss" )); } } // Hey come back! NPCInfo->goalEntity = target; if(target == NPC->enemy) NPCInfo->goalRadius = 60; else NPCInfo->goalRadius = 32; if(!NPC_MoveToGoal(qtrue)) { //cant go there on our first try, abort. //this really isnt the best way... but if it cant reach the point, it will just sit there doing nothing. NPCInfo->goalEntity = NPC->client->leader; //stop chasing the enemy if we were told to, and return to the player NPCInfo->scriptFlags &= ~SCF_CHASE_ENEMIES; } } //call this even if we do have an enemy, for enemy proximity detection if ( /*!NPC->enemy && */ NPCInfo->enemyCheckDebounceTime < level.time ) { // check twice a second to find a new enemy Seeker_FindEnemy(); NPCInfo->enemyCheckDebounceTime = level.time + 500; } //play our proximity beep if(NPC->genericValue3 && NPC->fly_sound_debounce_time > 0 && NPC->fly_sound_debounce_time < level.time) { G_Sound(NPC, CHAN_AUTO, NPC->genericValue3); NPC->fly_sound_debounce_time = -1; } NPC_UpdateAngles( qtrue, qtrue ); #else vec3_t pt, dir; float dis; float minDistSqr = MIN_DISTANCE_SQR; gentity_t *closestPlayer = NULL; Seeker_MaintainHeight(); closestPlayer = FindClosestPlayer(NPC->r.currentOrigin, NPC->client->playerTeam); if(!closestPlayer) { //in MP it's actually possible that there's no players on our team at the moment. return; } dis = DistanceHorizontalSquared( NPC->r.currentOrigin, closestPlayer->r.currentOrigin ); if ( NPC->client->NPC_class == CLASS_BOBAFETT ) { if ( TIMER_Done( NPC, "flameTime" ) ) { minDistSqr = 200*200; } } if ( dis < minDistSqr ) { // generally circle the player closely till we take an enemy..this is our target point if ( NPC->client->NPC_class == CLASS_BOBAFETT ) { pt[0] = closestPlayer->r.currentOrigin[0] + cos( level.time * 0.001f + NPC->random ) * 250; pt[1] = closestPlayer->r.currentOrigin[1] + sin( level.time * 0.001f + NPC->random ) * 250; if ( NPC->client->jetPackTime < level.time ) { pt[2] = closestPlayer->r.currentOrigin[2] - 64; } else { pt[2] = closestPlayer->r.currentOrigin[2] + 200; } } else { pt[0] = closestPlayer->r.currentOrigin[0] + cos( level.time * 0.001f + NPC->random ) * 56; pt[1] = closestPlayer->r.currentOrigin[1] + sin( level.time * 0.001f + NPC->random ) * 56; pt[2] = closestPlayer->r.currentOrigin[2] + 40; } VectorSubtract( pt, NPC->r.currentOrigin, dir ); VectorMA( NPC->client->ps.velocity, 0.8f, dir, NPC->client->ps.velocity ); } else { if ( NPC->client->NPC_class != CLASS_BOBAFETT ) { if ( TIMER_Done( NPC, "seekerhiss" )) { TIMER_Set( NPC, "seekerhiss", 1000 + random() * 1000 ); G_Sound( NPC, CHAN_AUTO, G_SoundIndex( "sound/chars/seeker/misc/hiss" )); } } // Hey come back! NPCInfo->goalEntity = closestPlayer; NPCInfo->goalRadius = 32; NPC_MoveToGoal( qtrue ); NPC->s.owner = closestPlayer->s.number; } if ( NPCInfo->enemyCheckDebounceTime < level.time ) { // check twice a second to find a new enemy Seeker_FindEnemy(); NPCInfo->enemyCheckDebounceTime = level.time + 500; } NPC_UpdateAngles( qtrue, qtrue ); #endif //[/SeekerItemNpc] }