Beispiel #1
0
void CDestructibleModel::RegisterDestroyedStimulus()
{
	// Register audio and visual stimulus if specified.

	if( (m_nDestroyAlarmLevel > 0) && (m_fStimRadius > 0.f) )
	{
		LTVector vPos;
		g_pLTServer->GetObjectPos(m_hObject, &vPos);

		// Extract who caused an explosion.

		HOBJECT hDamager = m_hLastDamager;
		if( IsExplosion( hDamager ) )
		{
			Explosion* pExplosion = (Explosion*)g_pLTServer->HandleToObject(m_hLastDamager);
			hDamager = pExplosion->GetFiredFrom();
		}

		// If damager is still not a character (possibly because an explosion was triggered), assume player.
		// Better solution - set the alignment of the damager on the explosion?

		if( !IsCharacter( hDamager ) )
		{
			CPlayerObj *pPlayer = g_pCharacterMgr->FindPlayer();
			if ( pPlayer )
			{
				hDamager = pPlayer->m_hObject;
			}
		}

		if ( IsCharacter(hDamager) )
		{
			CCharacter* pCharacter = (CCharacter*)g_pLTServer->HandleToObject(hDamager);
			if ( pCharacter )
			{
				// Register the disturbance sound.

				StimulusRecordCreateStruct DisturbanceSoundSCS( kStim_DisturbanceSound, pCharacter->GetAlignment(), vPos, hDamager );
				DisturbanceSoundSCS.m_hStimulusTarget = m_hObject;
				DisturbanceSoundSCS.m_flAlarmScalar = (float)m_nDestroyAlarmLevel;
				DisturbanceSoundSCS.m_flRadiusScalar = m_fStimRadius;
				g_pAIStimulusMgr->RegisterStimulus( DisturbanceSoundSCS );

				// Register the visible disturbance.

				StimulusRecordCreateStruct DisturbanceVisibleSCS( kStim_DisturbanceVisible, pCharacter->GetAlignment(), vPos, hDamager );
				DisturbanceVisibleSCS.m_hStimulusTarget = m_hObject;
				DisturbanceVisibleSCS.m_flAlarmScalar = (float)(m_nDestroyAlarmLevel + 1);
				DisturbanceVisibleSCS.m_flRadiusScalar = m_fStimRadius;
				m_eStimID = g_pAIStimulusMgr->RegisterStimulus( DisturbanceVisibleSCS );
			}
		}
	}
}
void CAIActionReactToDanger::ActivateAction( CAI* pAI, CAIWorldState& wsWorldStateGoal )
{
	super::ActivateAction( pAI, wsWorldStateGoal );

	// Bail if we are not aware of danger.

	CAIWMFact factQuery;
	factQuery.SetFactType( kFact_Danger );
	CAIWMFact* pFact = pAI->GetAIWorkingMemory()->FindWMFact( factQuery );
	if( !pFact )
	{
		return;
	}

	// Set animate state.

	pAI->SetState( kState_Animate );

	// Set flinch animation.

	CAnimationProps	animProps;
	animProps.Set( kAPG_Posture, kAP_POS_Crouch );
	animProps.Set( kAPG_Weapon, pAI->GetAIBlackBoard()->GetBBPrimaryWeaponProp() );
	animProps.Set( kAPG_WeaponPosition, kAP_WPOS_Up );
	animProps.Set( kAPG_Activity, kAP_ATVT_Distress );
	animProps.Set( kAPG_Action, kAP_ACT_Idle );

	CAIStateAnimate* pStateAnimate = (CAIStateAnimate*)( pAI->GetState() );
	pStateAnimate->SetAnimation( animProps, !LOOP );

	// Do NOT play a threat sound if threatened by a Turret.
	// Instead, allow turret targeting to play something appropriate.

	if( IsPlayer( pFact->GetSourceObject() ) )
	{
		CPlayerObj* pPlayer = (CPlayerObj*)g_pLTServer->HandleToObject( pFact->GetSourceObject() );
		if( pPlayer && pPlayer->GetTurret() )
		{
			return;
		}
	}

	// Play threat sound.

	// "Fire!"

	if( IsAINode( pFact->GetSourceObject() ) )
	{
		EnumAISoundType eAISound = kAIS_Danger;
		AINode* pNode = (AINode*)g_pLTServer->HandleToObject( pFact->GetSourceObject() );
		if( pNode && pNode->GetType() == kNode_Stimulus )
		{
			AINodeStimulus* pNodeStim = (AINodeStimulus*)pNode;
			if( pNodeStim )
			{
				eAISound = pNodeStim->GetAISoundType();
			}
		}
		g_pAISoundMgr->RequestAISound( pAI->m_hObject, eAISound, kAISndCat_Event, NULL, 0.f );
	}

	// "Watch out grenade!"
	// "Shit!"

	else if( IsKindOf( pFact->GetSourceObject(), "CProjectile" ) )
	{
		// Don't say anything if ally threw grenade.

		CProjectile* pProjectile = (CProjectile*)g_pLTServer->HandleToObject( pFact->GetSourceObject() );
		if( pProjectile && IsCharacter( pProjectile->GetFiredFrom() ) )
		{
			CCharacter *pChar = (CCharacter*)g_pLTServer->HandleToObject( pProjectile->GetFiredFrom() );
			if( pChar && kCharStance_Like != g_pCharacterDB->GetStance( pAI->GetAlignment(), pChar->GetAlignment() ) )
			{
				ENUM_AI_SQUAD_ID eSquad = g_pAICoordinator->GetSquadID( pAI->m_hObject );
				CAISquad* pSquad = g_pAICoordinator->FindSquad( eSquad );
				if( pSquad && pSquad->GetNumSquadMembers() > 1 )
				{
					g_pAISoundMgr->RequestAISound( pAI->m_hObject, kAIS_GrenadeThreat, kAISndCat_Event, NULL, 0.f );
				}
				else {
					g_pAISoundMgr->RequestAISound( pAI->m_hObject, kAIS_GrenadeThreatAlone, kAISndCat_Event, NULL, 0.f );
				}
			}
		}
	}

	// "Shit"

	else 
	{
		g_pAISoundMgr->RequestAISound( pAI->m_hObject, kAIS_GrenadeThreatAlone, kAISndCat_Event, NULL, 0.f );
	}



	// Search for the source of the danger.

	LTVector vDangerPos = pFact->GetPos();
	SearchForDangerOrigin( pAI, vDangerPos );
}