//[CoOp] //Replaced with SP version static void Howler_Patrol( void ) { gentity_t *ClosestPlayer = FindClosestPlayer(NPC->r.currentOrigin, NPC->client->enemyTeam); NPCInfo->localState = LSTATE_CLEAR; //If we have somewhere to go, then do that if ( UpdateGoal() ) { NPC_Howler_Move( 100 ); } if(ClosestPlayer) {//attack enemy players that are close. if(Distance(ClosestPlayer->r.currentOrigin, NPC->r.currentOrigin) < 256 * 256) { G_SetEnemy( NPC, ClosestPlayer ); } } if ( NPC_CheckEnemyExt( qtrue ) == qfalse ) { Howler_Idle(); return; } Howler_Attack( 0.0f, qtrue ); }
//Checks to see if EventSeePlayer should be fired //monster sez: Do I see the player void cMonster::CheckEventSeePlayer(void) { // TODO: Rewrite this to use cWorld's DoWithPlayers() cPlayer * Closest = FindClosestPlayer(); if (Closest != NULL) { EventSeePlayer(Closest); } }
void cWolf::Tick(float a_Dt, cChunk & a_Chunk) { if (!IsAngry()) { cMonster::Tick(a_Dt, a_Chunk); } else { super::Tick(a_Dt, a_Chunk); } if (IsSitting()) { m_bMovingToDestination = false; } cPlayer * a_Closest_Player = FindClosestPlayer(); if (a_Closest_Player != NULL) { switch (a_Closest_Player->GetEquippedItem().m_ItemType) { case E_ITEM_BONE: case E_ITEM_RAW_BEEF: case E_ITEM_STEAK: case E_ITEM_RAW_CHICKEN: case E_ITEM_COOKED_CHICKEN: case E_ITEM_ROTTEN_FLESH: { if (!IsBegging()) { SetIsBegging(true); m_World->BroadcastEntityMetadata(*this); } Vector3f a_NewDestination = a_Closest_Player->GetPosition(); a_NewDestination.y = a_NewDestination.y + 1; // Look at the head of the player, not his feet. m_Destination = Vector3f(a_NewDestination); m_bMovingToDestination = false; break; } default: { if (IsBegging()) { SetIsBegging(false); m_World->BroadcastEntityMetadata(*this); } } } } if (IsTame()) { TickFollowPlayer(); } }
//[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] }