// ----------------------------------------------------------------------- // // // ROUTINE: CAIGoalCatch::ActivateGoal // // PURPOSE: Activate goal. // // ----------------------------------------------------------------------- // void CAIGoalCatch::ActivateGoal(void) { super::ActivateGoal(); if (m_hStimulusTarget==LTNULL) { SetCurImportance(0); AITRACE(AIShowGoals, ( m_pAI->m_hObject, "Aborting Goal %s\n", s_aszGoalTypes[GetGoalType()] ) ); return; } // Ignore senses other than see enemy. m_pAI->SetCurSenseFlags( kSense_SeeEnemy | kSense_SeeDangerousProjectile | kSense_SeeCatchableProjectile ); m_pGoalMgr->LockGoal(this); m_pAI->SetState( kState_HumanCatch ); // Set state specific information.. CAIHumanStateCatch* pCatchInstance = (CAIHumanStateCatch*)m_pAI->GetState(); // Save the object we intend to catch pCatchInstance->SetObjectToCatch( m_hStimulusTarget ); // Set the animations to use pCatchInstance->SetAnimationSequence( kAP_StartCatch, kAP_HoldCatch, kAP_EndCatch ); }
void CAIGoalGuard::RecalcImportance() { // Find a node. if(!m_hGuardNode) { FindGuardNode(); } // Check status. AINodeGuard* pGuardNode = (AINodeGuard*)g_pLTServer->HandleToObject(m_hGuardNode); if( pGuardNode ) { m_bInRadius = LTTRUE; LTFLOAT fDistSqr = m_pAI->GetPosition().DistSqr( pGuardNode->GetPos() ); // There is a guard node, and we are outside of the return radius, // so guard goal gets its base importance. if( fDistSqr > pGuardNode->GetRadiusSqr() ) { // Ignore the Guard node's radius while AI is assigned a Talk node. if( ( GetGoalType() == kGoal_Guard ) && ( g_pAINodeMgr->FindOwnedNode( kNode_Talk, m_pAI->m_hObject ) ) ) { m_fCurImportance = 0.f; return; } SetCurToBaseImportance(); m_bInRadius = LTFALSE; } // We are inside the guard radius, so guard goal has minimum importance. // Only give goal any importance if it was previously at base importance. else if( m_fCurImportance > m_fMinImportance ) { m_fCurImportance = m_fMinImportance; } return; } // No guard node. m_bInRadius = LTFALSE; m_fCurImportance = 0.f; }
void CAIGoalAbstractUseObject::SetStateUseObject() { m_pAI->SetState( GetUseObjectState() ); AINodeUseObject* pNodeUseObject = (AINodeUseObject*)g_pLTServer->HandleToObject(m_hNodeUseObject); if( !pNodeUseObject ) { AIASSERT( NULL, m_pAI->m_hObject, "CAIGoalAbstractUseObject::SetStateUseObject: AINodeUseObject is NULL."); return; } CAIHumanStateUseObject* pStateUseObject = (CAIHumanStateUseObject*)(m_pAI->GetState()); pStateUseObject->StateHandlesNodeLocking( LTFALSE ); // Bail if there is any problem setting the node. if( !pStateUseObject->SetNode(pNodeUseObject) ) { AITRACE(AIShowGoals, ( m_pAI->m_hObject, "Unable to set UseObject node %s.", ::ToString( pNodeUseObject->GetName() ) ) ); m_hLastNodeUseObject = pNodeUseObject->m_hObject; CompleteUseObject(); return; } pStateUseObject->SetWeaponPosition(m_eWeaponPosition); pStateUseObject->SetRequireBareHands( m_bRequireBareHands ); pStateUseObject->SetAllowDialogue(m_bAllowDialogue); pStateUseObject->TurnOnLights( m_bTurnOnLights ); pStateUseObject->TurnOffLights( m_bTurnOffLights ); // Find command string for AINodeType matching UseObject. AIGBM_GoalTemplate* pTemplate = g_pAIGoalButeMgr->GetTemplate( GetGoalType() ); AIASSERT(pTemplate->cAttractors > 0, m_pAI->m_hObject, "CAIGoalAbstractUseObject::ActivateGoal: Goal has no attractors."); HSTRING hstrCmd; for(uint32 iAttractor=0; iAttractor < pTemplate->cAttractors; ++iAttractor) { hstrCmd = pNodeUseObject->GetSmartObjectCommand(pTemplate->aAttractors[iAttractor]); if(hstrCmd != LTNULL) { pStateUseObject->SetSmartObjectCommand(hstrCmd); break; } } // Ensure that node is setup to be requested type of attractor. if( !hstrCmd ) { AIASSERT( 0, m_pAI->m_hObject, "CAIGoalAbstractUseObject::ActivateGoal: No command string found for attractors."); m_fCurImportance = 0.f; } }
void CAIGoalDisappearReappear::DeactivateGoal() { super::DeactivateGoal(); // Goals DisappearReappear and DisappearReappearEvasive should share timing info. if( GetGoalType() != kGoal_DisappearReappearEvasive ) { CAIGoalAbstract* pGoal = m_pGoalMgr->FindGoalByType( kGoal_DisappearReappearEvasive ); if( pGoal && ( m_fNextUpdateTime > pGoal->GetNextUpdateTime() ) ) { pGoal->SetNextUpdateTime( m_fNextUpdateTime ); } } }
void CAIGoalDisappearReappearEvasive::ResetNextDisappearTime() { // All AIs using this goal share timing info. AIGBM_GoalTemplate* pTemplate = g_pAIGoalButeMgr->GetTemplate( GetGoalType() ); LTFLOAT fNextDisappearTime = 0.f; if( pTemplate->fFrequencyMax > 0.f ) { LTFLOAT fCurTime = g_pLTServer->GetTime(); fNextDisappearTime = fCurTime + GetRandom(pTemplate->fFrequencyMin, pTemplate->fFrequencyMax); } g_pAICentralKnowledgeMgr->RemoveAllKnowledge( kCK_NextDisappearTime, m_pAI ); g_pAICentralKnowledgeMgr->RegisterKnowledge( kCK_NextDisappearTime, m_pAI, g_pLTServer->HandleToObject(m_hStimulusSource), LTFALSE, fNextDisappearTime, LTTRUE); }
AINode* CAIGoalAttackProp::HandleGoalAttractors() { // Check if already attacking a prop. if( m_pAI->GetState()->GetStateType() != kState_HumanAttackProp ) { CAIHuman* pAIHuman = (CAIHuman*)m_pAI; if( pAIHuman->HasHolsterString() || pAIHuman->GetPrimaryWeapon()) { AIGBM_GoalTemplate* pTemplate = g_pAIGoalButeMgr->GetTemplate( GetGoalType() ); AIASSERT(pTemplate->cAttractors > 0, m_pAI->m_hObject, "CAIGoalAbstract::HandleGoalAttractors: Goal has no attractors."); // Check if attractors are triggering activateability. AINode* pNode; for(uint32 iAttractor=0; iAttractor < pTemplate->cAttractors; ++iAttractor) { pNode = g_pAINodeMgr->FindNearestNodeInRadius(m_pAI, pTemplate->aAttractors[iAttractor], m_pAI->GetPosition(), pTemplate->fAttractorDistSqr * m_fBaseImportance, LTTRUE); if(pNode != LTNULL) { HOBJECT hObject; if ( LT_OK == FindNamedObject(pNode->GetObject(), hObject) ) { Prop* pProp = (Prop*)g_pLTServer->HandleToObject(hObject); if(pProp->GetState() != kState_PropDestroyed) { AIASSERT(pNode->GetType() == kNode_UseObject, m_pAI->m_hObject, "CAIGoalAttackProp::HandleGoalAttractors: AINode is not of type UseObject."); m_hNode = pNode->m_hObject; SetCurToBaseImportance(); return pNode; } } // Disable node if prop has been destroyed. pNode->Disable(); } } } m_hNode = LTNULL; } return LTNULL; }
LTBOOL CAIGoalGuard::HandleNameValuePair(const char *szName, const char *szValue) { AIASSERT(szName && szValue, m_pAI->m_hObject, "CAIGoalGuard::HandleNameValuePair: Name or value is NULL."); if( super::HandleNameValuePair(szName, szValue) ) { return LTTRUE; } if ( !_stricmp(szName, "NODE") ) { // If Goal was already active (walking to previous guard node) // Reset the goal. if( m_pGoalMgr->IsCurGoal( this ) ) { m_pAI->SetState( kState_HumanIdle ); } AINode* pNode = g_pAINodeMgr->GetNode(szValue); if( pNode ) { SetGuardNode( pNode ); RecalcImportance(); AITRACE( AIShowGoals, ( m_pAI->m_hObject, "CAIGoal%s: NODE=%s", s_aszGoalTypes[GetGoalType()], ::ToString( pNode->GetName() ) ) ); } else { AIError( "%s Cannot find node! CAIGoal%s: NODE=%s", m_pAI->GetName(), s_aszGoalTypes[GetGoalType()], szValue ); } return LTTRUE; } return LTFALSE; }
//---------------------------------------------------------------------------- // // ROUTINE: CAIGoalResurrecting::HandleNameValuePair() // // PURPOSE: // //---------------------------------------------------------------------------- /*virtual*/ LTBOOL CAIGoalResurrecting::HandleNameValuePair(const char* szName,const char* szValue) { if ( !strcmp( szName, "RESETGOAL" )) { const CAIGoalAbstract* pCurGoal = m_pAI->GetGoalMgr()->GetCurrentGoal(); bool bIsThisGoalAIsCurrentGoal = ( (pCurGoal==NULL) ? (false) : (pCurGoal->GetGoalType()==GetGoalType()) ); if ( !bIsThisGoalAIsCurrentGoal ) { return LTFALSE; } // const CAIGoalAbstract* pCurGoal = m_pAI->GetGoalMgr()->GetCurrentGoal(); // bool bIsThisGoalAIsCurrentGoal = ( (pCurGoal==NULL) ? (false) : (pCurGoal->GetGoalType()==GetGoalType()) ); // if ( !bIsThisGoalAIsCurrentGoal ) // { // CAIGoalAbstract* pGoal = GetGoalMgr()->FindGoalByType( kGoal_Resurrecting ); // if ( pGoal != NULL ) // { // // If we have the goal, but it is not active, then do nothing // // because the Resurrecting goal either has not started, or // // some other goal has trumped it. // } // else // { // // If we do not have the goal, then this is an error condition // // because we cannot legally be here! // AIASSERT( 0, m_pAI->m_hObject, "Reseting Resurrect Goal when not active." ); // } // } CAIState* pState = m_pAI->GetState(); if ( !pState ) { AIASSERT( 0, m_pAI->m_hObject, "Reseting Resurrect Goal with no state." ); return LTFALSE; } switch(pState->GetStateType()) { case kState_HumanResurrecting: // If we are still resurrecting, do nothing! break; case kState_HumanAware: // If we are currently aware, then reset the Goal m_bReactivateGoalOnUpdate = LTTRUE; break; case kState_HumanSearch: // If we are currently searching, then reset the Goal m_bReactivateGoalOnUpdate = LTTRUE; break; // Unexpected State. default: AIASSERT(0, m_pAI->m_hObject, "CAIGoalResurrecting::UpdateGoal: Unexpected State."); } } return LTFALSE; }
//---------------------------------------------------------------------------- // // ROUTINE: CAIGoalResurrecting::HandleGoalSenseTrigger() // // PURPOSE: TEMP -- allow a trigger to cause goal entry. // //---------------------------------------------------------------------------- /*virtual*/ LTBOOL CAIGoalResurrecting::HandleGoalSenseTrigger(AISenseRecord* pSenseRecord ) { if ( !CAIGoalAbstractSearch::HandleGoalSenseTrigger( pSenseRecord )) { return LTFALSE; } else { const CAIGoalAbstract* pCurGoal = m_pAI->GetGoalMgr()->GetCurrentGoal(); bool bIsThisGoalAIsCurrentGoal = ( (pCurGoal==NULL) ? (false) : (pCurGoal->GetGoalType()==GetGoalType()) ); if ( !bIsThisGoalAIsCurrentGoal ) { return LTTRUE; } if( m_pAI->GetState() && m_pAI->GetState()->GetStateType() != kState_HumanResurrecting ) { return LTTRUE; } } return LTFALSE; }
AINode* CAIGoalAbstractUseObject::HandleGoalAttractors() { // Do not search for attractors if goal is already active. // Do not search on first update, to allow commands a chance to disable nodes. // Do not search if AI has any damage flags set (e.g. sleeping damage). if( m_pGoalMgr->IsCurGoal(this) || m_pAI->IsFirstUpdate() || m_pAI->GetDamageFlags() ) { return LTNULL; } // If this goal reacts to stimulus, check if it has been too // long since stimulation. AIGBM_GoalTemplate* pTemplate = g_pAIGoalButeMgr->GetTemplate( GetGoalType() ); if( ( pTemplate->flagSenseTriggers != kSense_None ) && ( !m_hStimulusSource ) ) { return LTNULL; } // Lock the last UseObject node, so that we don't try to use it again. BlockAttractorNodeFromSearch( m_hLastNodeUseObject ); // Find the nearest attractor. AINode* pNode = FindNearestAttractorNode(); if(pNode != LTNULL) { AIASSERT(pNode->GetType() == kNode_UseObject, m_pAI->m_hObject, "CAIGoalAbstractUseObject::HandleGoalAttractors: AINode is not of type UseObject."); AINodeUseObject* pNodeUseObject = (AINodeUseObject*)pNode; if( pNodeUseObject->HasObject() && !pNodeUseObject->GetHObject() ) { pNode = LTNULL; m_fCurImportance = 0.f; AIASSERT( 0, pNodeUseObject->m_hObject, "CAIGoalAbstractUseObject::HandleGoalAttractors: AINodeUseObject points to invalid object" ); } else if( pNodeUseObject->IsOneWay() && ( pNodeUseObject->GetForward().Dot( m_pAI->GetForwardVector() ) < 0.0f ) ) { pNode = LTNULL; m_fCurImportance = 0.f; } else { AITRACE(AIShowGoals, ( m_pAI->m_hObject, "Setting node: %s", ::ToString( pNode->GetName() ) ) ); m_hNodeUseObject = pNode->m_hObject; SetCurToBaseImportance(); } } if( !pNode ) { ClearUseObjectNode(); m_hStimulusSource = LTNULL; } // If we locked a node prior to the search, unlock it. UnblockAttractorNodeFromSearch( m_hLastNodeUseObject ); return pNode; }