LTBOOL CAIGoalDrawWeapon::HandleDamage(const DamageStruct& damage) { super::HandleDamage( damage ); // Activate the goal. CAIHuman* pAIHuman = (CAIHuman*)m_pAI; if( pAIHuman->HasHolsterString() && !pAIHuman->GetPrimaryWeapon() ) { m_bRequiresImmediateResponse = LTTRUE; SetCurToBaseImportance(); } // HACK: for TO2 AI with grenades. else if( ( m_pAI->GetPrimaryWeaponType() == kAIWeap_Thrown ) && pAIHuman->HasHolsterString() ) { m_bRequiresImmediateResponse = LTTRUE; SetCurToBaseImportance(); } // END HACK // Always return false to allow normal damage handling. return LTFALSE; }
LTBOOL CAIGoalDisappearReappearEvasive::HandleNameValuePair(const char *szName, const char *szValue) { ASSERT(szName && szValue); if ( !_stricmp(szName, "NOW") ) { AITRACE( AIShowGoals, ( m_pAI->m_hObject, "GoalDisappearReappearEvasive: NOW=1" ) ); m_bForceDisappear = LTTRUE; m_bRequiresImmediateResponse = LTTRUE; SetCurToBaseImportance(); return LTTRUE; } else if ( !_stricmp(szName, "OVERRIDEDIST") ) { m_fReappearDistOverride = (LTFLOAT)atof( szValue ); AITRACE( AIShowGoals, ( m_pAI->m_hObject, "GoalDisappearReappearEvasive: OVERRIDEDIST=%.2f", m_fReappearDistOverride ) ); return LTTRUE; } else if ( !_stricmp(szName, "DELAY") ) { m_fReappearDelay = (LTFLOAT)atof( szValue ); AITRACE( AIShowGoals, ( m_pAI->m_hObject, "GoalDisappearReappearEvasive: DELAY=%.2f", m_fReappearDelay ) ); return LTTRUE; } return LTFALSE; }
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 CAIGoalDisappearReappearEvasive::RecalcImportance() { // If we're unarmed, disappear and reappear with a weapon. CAIHuman* pAIHuman = (CAIHuman*)m_pAI; if( ( !m_pAI->GetPrimaryWeapon() ) && ( !pAIHuman->HasHolsterString() ) && m_pAI->HasBackupHolsterString() ) { m_bForceDisappear = LTTRUE; m_fNextUpdateTime = 0.f; SetCurToBaseImportance(); } }
void CAIGoalTalk::StartDialogue() { // Flag that the process has been kicked off. // AI may need to get in position before starting to talk. if( !m_bStartedDialog ) { SetCurToBaseImportance(); if( m_pGoalMgr->IsCurGoal( this ) ) { GotoNode(); } m_bStartedDialog = LTTRUE; m_bInTalkPosition = LTFALSE; } }
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; }
void CAIGoalRespondToBackup::RecalcImportance() { // Goal activates when AI is stimulated by a backup node's AllyDistress, // ally has arrived at (and unlocked) the node. if( m_hNodeBackup ) { m_pAI->SetCurSenseFlags( kSense_SeeEnemy | kSense_SeeDangerousProjectile | kSense_SeeCatchableProjectile ); AINodeBackup* pNodeBackup = (AINodeBackup*)g_pLTServer->HandleToObject( m_hNodeBackup ); if( !pNodeBackup->IsLocked() ) { if( m_cArrivalCount >= pNodeBackup->GetArrivalCount() ) { m_hNodeBackup = LTNULL; m_fCurImportance = 0.f; m_pAI->ResetBaseSenseFlags(); return; } // Check if AI thinks ally is crying wolf. if( m_cResponses < pNodeBackup->GetCryWolfCount() ) { m_vEnemySeenPos = pNodeBackup->GetEnemySeenPos(); SetCurToBaseImportance(); return; } else { m_pAI->PlaySound( kAIS_BackupCryWolf, LTFALSE ); m_hNodeBackup = LTNULL; m_pAI->ResetBaseSenseFlags(); } } } m_fCurImportance = 0.f; }
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; }