void CAIStateAnimate::DepartNode() { // Depart from a node. 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->HandleAIDeparture( m_pAI ); } } }
void CAIActionAttackLungeUncloaked::ActivateAction( CAI* pAI, CAIWorldState& wsWorldStateGoal ) { super::ActivateAction( pAI, wsWorldStateGoal ); // Record who is lunging on the blackboard. // Only one AI may lunge at a time. CAIWMFact* pFact = g_pAIWorkingMemoryCentral->CreateWMFact( kFact_Knowledge ); if (pFact) { pFact->SetKnowledgeType( kKnowledge_Lunging, 1.f ); pFact->SetSourceObject( pAI->m_hObject, 1.f ); } // Depart from a node. SAIWORLDSTATE_PROP* pProp = pAI->GetAIWorldState()->GetWSProp( kWSK_AtNode, pAI->m_hObject ); if( pProp && pProp->hWSValue ) { AINode* pNode = (AINode*)g_pLTServer->HandleToObject( pProp->hWSValue ); if( pNode ) { pNode->HandleAIDeparture( pAI ); } } // Turn on touch handling pAI->GetAIBlackBoard()->SetBBHandleTouch( kTouch_Damage ); // Do not move thru the target. pAI->GetAIMovement()->AllowTargetPenetration( false ); // Torso tracking. pAI->GetAIBlackBoard()->SetBBTargetTrackerFlags( kTrackerFlag_LookAt ); pAI->GetAIBlackBoard()->SetBBFaceTarget( true ); // Turn towards target, but don't track. HOBJECT hTarget = pAI->GetAIBlackBoard()->GetBBTargetObject(); pAI->GetAIBlackBoard()->SetBBFaceObject( hTarget ); // This Actions does not Uncloak the AI. // It is assumed that the AI will uncloak thru a // DESIRE modelstring in the lunge animation. // This allows the AI to uncloak in mid-lunge. }
void CAIActionSurpriseAttackLaunch::ActivateAction( CAI* pAI, CAIWorldState& wsWorldStateGoal ) { super::ActivateAction( pAI, wsWorldStateGoal ); // Verify we selected a valid action. EnumAnimProp eAction = GetAtNodeAttackProp( *pAI->GetAIWorldState(), pAI->GetHOBJECT(), pAI->GetAIBlackBoard()->GetBBTargetObject() ); if ( kAP_Invalid == eAction ) { AIASSERT( 0, pAI->GetHOBJECT(), "CAIActionSurpriseAttackLaunch::ActivateAction: Failed to find an action despite passing precondition test." ); return; } // Verify the node specifies a smartobject. const AIDB_SmartObjectRecord* pSmartObject = GetAtNodeSmartObjectRecord( *pAI->GetAIWorldState(), pAI->GetHOBJECT() ); if ( !pSmartObject ) { AIASSERT( 0, pAI->GetHOBJECT(), "CAIActionSurpriseAttackLaunch::ActivateAction: Failed to smartobject for node despite passing precondition test." ); return; } // Notify the surprise node that it has been used. AINodeSurprise* pSurprise = GetSurpriseNode( *pAI->GetAIWorldState(), pAI->GetHOBJECT() ); if ( pSurprise ) { pSurprise->HandleSurpriseAttack(); } // Depart from a node (this must be done AFTER we get the node) SAIWORLDSTATE_PROP* pProp = pAI->GetAIWorldState()->GetWSProp( kWSK_AtNode, pAI->m_hObject ); if( pProp && pProp->hWSValue ) { AINode* pNode = (AINode*)g_pLTServer->HandleToObject( pProp->hWSValue ); if( pNode ) { pNode->HandleAIDeparture( pAI ); // Insure we call the PostActivate to fire off any commands/to // reset the activation time/to dispatch any post activate commands. AINodeSmartObject* pNodeSmartObject = AINodeSmartObject::DynamicCast( pNode->GetHOBJECT() ); if( pNodeSmartObject ) { pNodeSmartObject->PostActivate(); } } } // Get the nodes smartobject and replace the action with the action // determined dynamically. The activity specifies the direction/etc. CAnimationProps Props = pSmartObject->Props; Props.Set( kAPG_Action, eAction ); // Set the animation to play. pAI->SetState( kState_Animate ); CAIStateAnimate* pAnimate = (CAIStateAnimate*)pAI->GetState(); pAnimate->SetAnimation( Props, !LOOP ); // Torso tracking. pAI->GetAIBlackBoard()->SetBBTargetTrackerFlags( kTrackerFlag_AimAt ); pAI->GetAIBlackBoard()->SetBBFaceTarget( false ); // Ignore the AIs radius when validating movement encoding, as this // animation should be fit to the geometry by level designers. pAI->GetAIBlackBoard()->SetBBMovementEncodeUseRadius( false ); }