Esempio n. 1
0
float Action_MoveToTarget::preCondition()
{
	/*
	 * Moving to the target has the following preconditions:
	 * - A target has been set.
	 * - The NPC is not in combat range.
	 *
	 * Here we take the fuzzy logic into account.
	 * If the npc is injured, the chance of fighting will decrease.
	 */

	if ( !m_ai )
	{
		return 0.0f;
	}

	P_CHAR currentVictim = m_ai->currentVictim();

	if ( !currentVictim || !validTarget( m_npc, currentVictim ) )
	{
		return 0.0f;
	}

	Q_UINT8 range = 1;
	P_ITEM weapon = m_npc->getWeapon();

	if ( weapon )
	{
		if ( weapon->hasTag( "range" ) )
		{
			range = weapon->getTag( "range" ).toInt();
		}
		else if ( weapon->basedef() )
		{
			range = weapon->basedef()->getIntProperty( "range", 1 );
		}
	}

	if ( m_npc->inRange( currentVictim, range ) )
		return 0.0f;

	// 1.0 = Full Health, 0.0 = Dead
	float diff = 1.0 - wpMax<float>( 0, ( m_npc->maxHitpoints() - m_npc->hitpoints() ) / ( float ) m_npc->maxHitpoints() );

	if ( diff <= m_npc->criticalHealth() / 100.0 )
	{
		return 0.0;
	}

	return 1.0;
}
Esempio n. 2
0
float Action_MoveToTarget::postCondition()
{
	/*
	 * Moving to the target has the following postconditions:
	 * - The target is not set anymore.
	 * - The NPC is within fight range.
	 * - The NPC is not injured above the critical line.
	 */

	if ( !m_ai )
	{
		return 1.0f;
	}

	P_CHAR currentVictim = m_ai->currentVictim();

	if ( !currentVictim || !validTarget( m_npc, currentVictim ) )
		return 1.0f;

	Q_UINT8 range = 1;
	P_ITEM weapon = m_npc->getWeapon();
	if ( weapon )
	{
		if ( weapon->hasTag( "range" ) )
		{
			range = weapon->getTag( "range" ).toInt();
		}
		else if ( weapon->basedef() )
		{
			range = weapon->basedef()->getIntProperty( "range", 1 );
		}
	}

	if ( m_npc->inRange( currentVictim, range ) )
		return 1.0f;

	// 1.0 = Full Health, 0.0 = Dead
	float diff = 1.0 - wpMax<float>( 0, ( m_npc->maxHitpoints() - m_npc->hitpoints() ) / ( float ) m_npc->maxHitpoints() );

	if ( diff <= m_npc->criticalHealth() / 100.0 )
	{
		return 1.0;
	}

	return 0.0;
}