예제 #1
0
bool AINodeValidatorOwnerNotLocked::Evaluate( AINode* pNode, uint32 dwFilteredStatusFlags, CAI* pAI ) const
{
	if( dwFilteredStatusFlags & kNodeStatus_OwnerNotLocked )
	{
		// Sanity check.

		if( !( pNode && pAI ) )
		{
			return false;
		}

		// Node has an owner.

		if( IsAINode( pNode->GetNodeOwner() ) )
		{
			// Fail if owner is not locked.

			AINode* pOwner = (AINode*)g_pLTServer->HandleToObject( pNode->GetNodeOwner() );
			if( pOwner && !pOwner->IsNodeLocked() )
			{
				return false;
			}

			// Fail if owner is locked by someone else.

			if( pOwner && ( pOwner->GetLockingAI() != pAI->m_hObject ) )
			{
				return false;
			}
		}
	}

	return true;
}
예제 #2
0
	int operator()(CAIWMFact* pFact)
	{
		// Ignore facts that are not node facts.
		// Ignore node facts with the wrong node type.
		// Ignore node facts whose object matches the hExclude.

		if( ( pFact->GetFactType() != kFact_Node ) ||
			( pFact->GetNodeType() != kNode_Stalk ))
		{
			return 0;
		}

		AINode* pNode = AINode::HandleToObject( pFact->GetTargetObject() );
		if( !pNode )
		{
			return 0;
		}

		// Bail if node is locked by someone else, disabled, or timed out.

		// TODO: Handle the AI locking the node.  This can work when code to 
		// handle an invalid node is written.
		if (pNode->GetHOBJECT() == m_hIgnoreStalkingNode)
		{
			return false;
		}

		if (pNode->IsNodeLocked()/* && pNode->GetLockingAI() != m_pAI->GetHOBJECT()*/)
		{
			return false;
		}

		if( pNode->IsNodeDisabled() || pNode->IsNodeTimedOut() )
		{
			return false;
		}

		// Require the AI be in the radius or region

		if (!pNode->IsAIInRadiusOrRegion( m_pAI, m_pAI->GetPosition(), 1.f ))
		{
			return 0;
		}

		// If AI is aware of a threat, ignore nodes that are invalid.

		if( m_hThreat && 
			( !pNode->IsNodeValid( m_pAI, m_pAI->GetPosition(), m_hThreat, kThreatPos_TargetPos, kNodeStatus_All ^ kNodeStatus_ThreatOutsideFOV) ) )
		{
			return 0;
		}

		// Failed to find a valid destination position.

		LTVector vDestination;
		if (!pNode->GetDestinationPosition(m_pAI, m_pAI->GetAIBlackBoard()->GetBBTargetPosition(), vDestination))
		{
			return 0;
		}

		// The stalking position is further from the AIs goal than the AI 
		// currently is (don't run backwards to stalk).

		float flNodeDestToAIDestDistSqr = vDestination.DistSqr(m_pAI->GetAIBlackBoard()->GetBBTargetReachableNavMeshPosition());
		if (flNodeDestToAIDestDistSqr > m_flDistanceToDestinationSqr)
		{
			return 0;
		}

		// Node is behind the AI.

		if (0 > m_pAI->GetForwardVector().Dot( vDestination - m_pAI->GetPosition()))
		{
			return 0;
		}

		// Already found a closer node.

		float flDistanceFromAISqr = vDestination.DistSqr(m_pAI->GetPosition());
		if (flDistanceFromAISqr > m_flBestDistanceFromAISqr)
		{
			return 0;
		}

		m_vBestPosition = vDestination;
		m_flBestDistanceFromAISqr = flDistanceFromAISqr;
		m_pBestFact = pFact;

		return 0;
	}