static bool CanSeeAPlayer(const TActor *a) { const Vec2i realPos = Vec2iFull2Real(a->Pos); for (int i = 0; i < MAX_PLAYERS; i++) { if (!IsPlayerAlive(i)) { continue; } const TActor *player = CArrayGet(&gActors, gPlayerIds[i]); const Vec2i playerRealPos = Vec2iFull2Real(player->Pos); // Can see player if: // - Clear line of sight, and // - If they are close, or if facing and they are not too far if (!AIHasClearShot(realPos, playerRealPos)) { continue; } const int distance = CHEBYSHEV_DISTANCE( realPos.x, realPos.y, playerRealPos.x, playerRealPos.y); const bool isClose = distance < 16 * 4; const bool isNotTooFar = distance < 16 * 30; if (isClose || (isNotTooFar && IsFacing(realPos, playerRealPos, a->direction))) { return true; } } return false; }
static bool IsFacingPlayer(TActor *actor, direction_e d) { for (int i = 0; i < MAX_PLAYERS; i++) { if (gPlayerIds[i] < 0) { continue; } const TActor *player = CArrayGet(&gActors, gPlayerIds[i]); if (IsPlayerAlive(i) && IsFacing(actor->Pos, player->Pos, d)) { return true; } } return false; }
int COtis :: TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType) { int ret; // make sure friends talk about it if player hurts talkmonsters... if ( !m_fHostile ) ret = CTalkMonster::TakeDamage(pevInflictor, pevAttacker, flDamage, bitsDamageType); else ret = CBaseMonster::TakeDamage(pevInflictor, pevAttacker, flDamage, bitsDamageType); if ( !IsAlive() || pev->deadflag == DEAD_DYING || m_fHostile ) return ret; if ( !m_fHostile ) { if ( m_MonsterState != MONSTERSTATE_PRONE && (pevAttacker->flags & FL_CLIENT) ) { m_flPlayerDamage += flDamage; // This is a heurstic to determine if the player intended to harm me // If I have an enemy, we can't establish intent (may just be crossfire) if ( m_hEnemy == NULL ) { // If the player was facing directly at me, or I'm already suspicious, get mad if ( (m_afMemory & bits_MEMORY_SUSPICIOUS) || IsFacing( pevAttacker, pev->origin ) ) { // Alright, now I'm pissed! PlaySentence( "OT_MAD", 4, VOL_NORM, ATTN_NORM ); Remember( bits_MEMORY_PROVOKED ); StopFollowing( TRUE ); } else { // Hey, be careful with that PlaySentence( "OT_SHOT", 4, VOL_NORM, ATTN_NORM ); Remember( bits_MEMORY_SUSPICIOUS ); } } else if ( !(m_hEnemy->IsPlayer()) && pev->deadflag == DEAD_NO ) PlaySentence( "OT_SHOT", 4, VOL_NORM, ATTN_NORM ); } } return ret; }
int CNPC_HL1Barney::OnTakeDamage_Alive( const CTakeDamageInfo &inputInfo ) { // make sure friends talk about it if player hurts talkmonsters... int ret = BaseClass::OnTakeDamage_Alive( inputInfo ); if ( !IsAlive() || m_lifeState == LIFE_DYING ) return ret; if ( m_NPCState != NPC_STATE_PRONE && ( inputInfo.GetAttacker()->GetFlags() & FL_CLIENT ) ) { // This is a heurstic to determine if the player intended to harm me // If I have an enemy, we can't establish intent (may just be crossfire) if ( GetEnemy() == NULL ) { // If the player was facing directly at me, or I'm already suspicious, get mad if ( HasMemory( bits_MEMORY_SUSPICIOUS ) || IsFacing( inputInfo.GetAttacker(), GetAbsOrigin() ) ) { // Alright, now I'm pissed! Speak( BA_MAD ); Remember( bits_MEMORY_PROVOKED ); StopFollowing(); } else { // Hey, be careful with that Speak( BA_SHOT ); Remember( bits_MEMORY_SUSPICIOUS ); } } else if ( !(GetEnemy()->IsPlayer()) && m_lifeState == LIFE_ALIVE ) { Speak( BA_SHOT ); } } return ret; }
int CFriend :: TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType) { // make sure friends talk about it if player hurts talkmonsters... int ret = CTalkMonster::TakeDamage(pevInflictor, pevAttacker, flDamage, bitsDamageType); if ( !IsAlive() || pev->deadflag == DEAD_DYING ) return ret; // LRC - if my reaction to the player has been overridden, don't do this stuff if (m_iPlayerReact) return ret; if ( m_MonsterState != MONSTERSTATE_PRONE && (pevAttacker->flags & FL_CLIENT) ) { // This is a heurstic to determine if the player intended to harm me // If I have an enemy, we can't establish intent (may just be crossfire) if ( m_hEnemy == NULL ) { // If the player was facing directly at me, or I'm already suspicious, get mad if ( (m_afMemory & bits_MEMORY_SUSPICIOUS) || IsFacing( pevAttacker, pev->origin ) ) { // Alright, now I'm pissed! if (m_iszSpeakAs) { char szBuf[32]; strcpy(szBuf,STRING(m_iszSpeakAs)); strcat(szBuf,"_MAD"); PlaySentence( szBuf, 4, VOL_NORM, ATTN_NORM ); } else { PlaySentence( "FG_MAD", 4, VOL_NORM, ATTN_NORM ); } Remember( bits_MEMORY_PROVOKED ); StopFollowing( TRUE ); } else { // Hey, be careful with that if (m_iszSpeakAs) { char szBuf[32]; strcpy(szBuf,STRING(m_iszSpeakAs)); strcat(szBuf,"_SHOT"); PlaySentence( szBuf, 4, VOL_NORM, ATTN_NORM ); } else { PlaySentence( "FG_SHOT", 4, VOL_NORM, ATTN_NORM ); } Remember( bits_MEMORY_SUSPICIOUS ); } } else if ( !(m_hEnemy->IsPlayer()) && pev->deadflag == DEAD_NO ) { if (m_iszSpeakAs) { char szBuf[32]; strcpy(szBuf,STRING(m_iszSpeakAs)); strcat(szBuf,"_SHOT"); PlaySentence( szBuf, 4, VOL_NORM, ATTN_NORM ); } else { PlaySentence( "FG_SHOT", 4, VOL_NORM, ATTN_NORM ); } } } return ret; }