Example #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;
}
Example #2
0
bool AINodeValidatorValidForFollow::Evaluate( uint32 dwFilteredStatusFlags, CAI* pAI, HOBJECT hNodeObject ) const
{
	// Node is always valid if there is no AI to consider.

	if( !pAI )
	{
		return true;
	}

	// Sensors are responsible for only keeping potentially valid nodes in memory.
	// While following, nodes that are not potentially valid should be filtered out.

	if( dwFilteredStatusFlags & kNodeStatus_ValidForFollow )
	{
		// Node does not exist.

		AINode* pNode = (AINode*)g_pLTServer->HandleToObject( hNodeObject );
		if( !pNode )
		{
			return false;
		}

		// Node is always valid if we are not following anyone.

		CAIWMFact factTaskQuery;
		factTaskQuery.SetFactType( kFact_Task );
		factTaskQuery.SetTaskType( kTask_Follow );
		CAIWMFact* pFact = pAI->GetAIWorkingMemory()->FindWMFact( factTaskQuery );
		if( !pFact )
		{
			return true;
		}

		// Node is valid if it is already locked by this AI, and we're following a leader.

		if( ( pAI->HasTarget( kTarget_Leader ) ) &&
			( pNode->GetLockingAI() == pAI->m_hObject ) )
  		{
  			return true;
		}

		// Node is invalid for follow if a fact for the node does not exist in working memory.

		CAIWMFact factQuery;
		factQuery.SetFactType( kFact_Node );
		factQuery.SetTargetObject( hNodeObject );
		pFact = pAI->GetAIWorkingMemory()->FindWMFact( factQuery );
		if( !pFact )
		{
			return false;
		}
	}

	return true;
}
Example #3
0
void CAISensorNodeCombat::FilterNodesValidForFollow( AIVALID_NODE_LIST& lstValidNodes )
{
	// This is kindof a hack to be filtering nodes for follwing inside of this sensor.
	// Maybe eventually this could be moved into a separate sensor that updates every
	// frame, but knows to only really do anything when nodes of some types have been
	// refreshed.

	// Bail if we are not following anyone.

	CAIWMFact factTaskQuery;
	factTaskQuery.SetFactType( kFact_Task );
	factTaskQuery.SetTaskType( kTask_Follow );
	CAIWMFact* pFact = m_pAI->GetAIWorkingMemory()->FindWMFact( factTaskQuery );
	if( !pFact )
	{
		return;
	}

	static AINODE_LIST lstFollowNodes;
	lstFollowNodes.resize( 0 );

	// Collect known follow nodes.

	AINodeFollow* pNodeFollow;
	AIWORKING_MEMORY_FACT_LIST::const_iterator itFact;
	const AIWORKING_MEMORY_FACT_LIST* pFactList = m_pAI->GetAIWorkingMemory()->GetFactList();
	for( itFact = pFactList->begin(); itFact != pFactList->end(); ++itFact )
	{
		// Ignore deleted facts.

		pFact = *itFact;
		if( pFact->IsDeleted() )
		{
			continue;
		}

		if( ( pFact->GetFactType() == kFact_Node ) &&
			( pFact->GetNodeType() == kNode_Follow ) )
		{
			pNodeFollow = (AINodeFollow*)g_pLTServer->HandleToObject( pFact->GetTargetObject() );
			if( pNodeFollow )
			{
				lstFollowNodes.push_back( pNodeFollow );
			}
		}
	}

	// If we are standing at a node of the correct type,
	// add it to the list of potentially valid nodes.
	// Ordinarily, locked nodes are ommitted, but in the case of 
	// following we need to consider the node we are at valid.

	SAIWORLDSTATE_PROP* pProp = m_pAI->GetAIWorldState()->GetWSProp( kWSK_AtNode, m_pAI->m_hObject );
	if( pProp && pProp->hWSValue )
	{
		AINode* pNode = (AINode*)g_pLTServer->HandleToObject( pProp->hWSValue );
		if( pNode && 
			( pNode->GetLockingAI() == m_pAI->m_hObject ) &&
			( pNode->GetType() == m_pSensorRecord->eNodeType ) )
		{
			SAIVALID_NODE ValidNode;
			ValidNode.hNode = pNode->m_hObject;
			ValidNode.fDistSqr = 0.f;

			lstValidNodes.push_back( ValidNode );
		}
	}


	// Remove nodes from list that are not valid for follow.

	HOBJECT hNode;
	bool bNodeIsValidForFollow;
	AINODE_LIST::iterator itNode;
	AIVALID_NODE_LIST::iterator itValidNode = lstValidNodes.begin();
	while( itValidNode != lstValidNodes.end() )
	{
		hNode = itValidNode->hNode;

		// Find the node listed in a follow node's list.

		bNodeIsValidForFollow = false;
		for( itNode = lstFollowNodes.begin(); itNode != lstFollowNodes.end(); ++itNode )
		{
			pNodeFollow = (AINodeFollow*)(*itNode);
			if( pNodeFollow &&
				pNodeFollow->GetWaitingNodes() &&
				pNodeFollow->GetWaitingNodes()->DoesContain( hNode ) )
			{
				bNodeIsValidForFollow = true;
				break;
			}
		}

		// Remove invalid node from list.

		if( !bNodeIsValidForFollow )
		{
			itValidNode = lstValidNodes.erase( itValidNode );
			continue;
		}

		// Continue iterating over list.

		++itValidNode;
	}
}