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; }
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; }