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