示例#1
0
文件: ai.c 项目: kodephys/cdogs-sdl
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;
}
示例#2
0
文件: ai.c 项目: kodephys/cdogs-sdl
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;
}
示例#4
0
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;
}
示例#5
0
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;
}