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;
}
Beispiel #3
0
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();
	}
}
Beispiel #5
0
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;
}