Ejemplo n.º 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;
			}
		}

		g_pAIStimulusMgr->RegisterStimulus( kStim_EnemyDisturbanceSound, m_nDestroyAlarmLevel, hDamager, m_hObject, vPos, m_fStimRadius );
		m_eStimID = g_pAIStimulusMgr->RegisterStimulus( kStim_EnemyDisturbanceVisible, m_nDestroyAlarmLevel + 1, hDamager, m_hObject, vPos, m_fStimRadius );
	}
}
Ejemplo n.º 2
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 );
			}
		}
	}
}
Ejemplo n.º 3
0
void Prop::HandleTouch(HOBJECT hToucher)
{
	// Only characters can touch props.

	if( ( hToucher != LTNULL ) &&
		( !IsCharacter(hToucher) ) &&
		( !IsExplosion(hToucher) ) )
	{
		return;
	}

	if ( (m_eState == kState_PropDestroyed)
		|| (m_eState == kState_PropKnocked) 
		|| (!(m_pDisturb && m_pDisturb->pPD)) )
	{
		return;
	}

	// Resolve the toucher to a character handle.

	HOBJECT hCharacter = LTNULL;
	if( IsCharacterHitBox( hToucher ) )
	{
		CCharacterHitBox* pHB = (CCharacterHitBox*)g_pLTServer->HandleToObject(hToucher);
		hCharacter = pHB->GetModelObject();
	}
	else if( IsExplosion( hToucher ) )
	{
		Explosion* pExplosion = (Explosion*)g_pLTServer->HandleToObject(hToucher);
		hCharacter = pExplosion->GetFiredFrom();
	}
	else if( IsCharacter( hToucher ) ) 
	{
		hCharacter = hToucher;
	}


	// Only players can touch (for now).
	if((hCharacter != LTNULL) && !IsPlayer(hCharacter)) return;

	if(m_eState == kState_PropTouching)
	{
		// Clear sound if done playing.

		ClearTouchSoundIfDone(LTFALSE);

		// Check if both sound and animation are done, or just the sound for a "knock."

		if( m_pDisturb->hTouchSound == LTNULL )
		{
			switch( m_pDisturb->eTouchAnimType )
			{
				// Touch animations reset.

				case kPA_Touch:
					ClearTouchAnimIfDone(m_pDisturb->hTouchAnim, LTFALSE);
					if( g_pLTServer->GetModelAnimation(m_hObject) != m_pDisturb->hTouchAnim )
					{
						m_eState = kState_PropDefault;
						return;
					}
					break;

				// Knock animations remain on the last frame forever.

				case kPA_Knock:
					if( MS_PLAYDONE & g_pLTServer->GetModelPlaybackState(m_hObject) )
					{
						m_bTouchable = LTFALSE;

						g_pCommonLT->SetObjectFlags(m_hObject, OFT_User, 0, USRFLG_CAN_ACTIVATE);

						m_eState = kState_PropKnocked;
						return;
					}
					break;
			}
		}
	}


	// Play the touch sound and animation.

	if( (m_eState == kState_PropDefault) && (hCharacter != LTNULL))
	{
        LTVector vPos;
		g_pLTServer->GetObjectPos(m_hObject, &vPos);

		// Play sound.
		PlayTouchSound(vPos);

		// Play animation.
		if(m_pDisturb->hTouchAnim != INVALID_ANI)
		{
			g_pLTServer->SetModelAnimation(m_hObject, m_pDisturb->hTouchAnim);
			g_pLTServer->SetModelLooping(m_hObject, LTFALSE);
			g_pLTServer->ResetModelAnimation(m_hObject);
		}

		// Register touch disturbance stimulus.

		if( (m_pDisturb->pPD->nTouchAlarmLevel > 0) && (m_pDisturb->pPD->fStimRadius > 0.f) )
		{
			g_pAIStimulusMgr->RegisterStimulus( kStim_EnemyDisturbanceSound, m_pDisturb->pPD->nTouchAlarmLevel, hCharacter, m_hObject, vPos, m_pDisturb->pPD->fStimRadius );

			// Props that are knocked over have a visual stimulus too.

			if( m_pDisturb->eTouchAnimType == kPA_Knock )
			{
				g_pAIStimulusMgr->RegisterStimulus( kStim_EnemyDisturbanceVisible, m_pDisturb->pPD->nTouchAlarmLevel + 1, hCharacter, m_hObject, vPos, m_pDisturb->pPD->fStimRadius );
			}
		}

		m_eState = kState_PropTouching;
	}

	// Update while playing touch sound and/or animation.
	SetNextUpdate(UPDATE_NEXT_FRAME);
}
Ejemplo n.º 4
0
void Prop::HandleHit( HOBJECT hDamager )
{
	if( ( hDamager != LTNULL ) &&
		( !IsCharacter(hDamager) ) &&
		( !IsExplosion(hDamager) ) )
	{
		return;
	}

	if( (m_eState == kState_PropDestroyed)
		|| (m_eState == kState_PropKnocked) 
		|| (!(m_pDisturb && m_pDisturb->pPD)) )
	{
		return;
	}

	// If we don't have a valid hit animation default to the touch animation...

	if( m_pDisturb->hHitAnim == INVALID_ANI )
		HandleTouch( hDamager );

	// Resolve the toucher to a character handle.

	HOBJECT hCharacter = LTNULL;
	if( IsCharacterHitBox( hDamager ) )
	{
		CCharacterHitBox* pHB = (CCharacterHitBox*)g_pLTServer->HandleToObject(hDamager);
		hCharacter = pHB->GetModelObject();
	}
	else if( IsExplosion( hDamager ) )
	{
		Explosion* pExplosion = (Explosion*)g_pLTServer->HandleToObject(hDamager);
		hCharacter = pExplosion->GetFiredFrom();
	}
	else if( IsCharacter( hDamager ) ) 
	{
		hCharacter = hDamager;
	}

	// Only characters can hit (for now).
	if((hCharacter != LTNULL) && !IsCharacter(hCharacter)) return;

	if(m_eState == kState_PropHit)
	{
		// Check if both sound and animation are done

		ClearHitSoundIfDone( LTFALSE );
		if( m_pDisturb->hHitSound == LTNULL )
		{
			ClearHitAnimIfDone( LTFALSE );
			if( g_pLTServer->GetModelAnimation(m_hObject) != m_pDisturb->hHitAnim )
			{
				m_eState = kState_PropDefault;
				return;
			}
		}
	}
	
	// Play the hit sound and animation.

	if( (m_eState == kState_PropDefault) && (hCharacter != LTNULL))
	{
        LTVector vPos;
		g_pLTServer->GetObjectPos(m_hObject, &vPos);

		// Play sound.
		PlayHitSound(vPos);

		// Play animation.
		if(m_pDisturb->hHitAnim != INVALID_ANI)
		{
			g_pLTServer->SetModelAnimation( m_hObject, m_pDisturb->hHitAnim );
			g_pLTServer->SetModelLooping( m_hObject, LTFALSE );
			g_pLTServer->ResetModelAnimation(m_hObject);
		}

		// Register touch disturbance stimulus.

		if( (m_pDisturb->pPD->nHitAlarmLevel > 0) && (m_pDisturb->pPD->fStimRadius > 0.f) )
		{
			g_pAIStimulusMgr->RegisterStimulus( kStim_EnemyDisturbanceSound, m_pDisturb->pPD->nHitAlarmLevel, hCharacter, m_hObject, vPos, m_pDisturb->pPD->fStimRadius );
		}

		m_eState = kState_PropHit;
	}

	// Update while playing touch sound and/or animation.
	SetNextUpdate(UPDATE_NEXT_FRAME);
}