⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 destructablemodel.cpp

📁 Blood 2全套源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

			// Check if still on something...
			if( m_bStandingOn )
			{
				// Start a sound, if it's not going already...
				if( !m_hSlidingSound )
				{
					pszSlidingSound = g_pServerDE->GetStringData( m_hstrSlidingSound );
					if( pszSlidingSound )
					{
						m_hSlidingSound = PlaySoundFromObject( m_hObject, pszSlidingSound, 1000.0f, SOUNDPRIORITY_MISC_LOW, DTRUE, DTRUE );
					}
				}

				bSlid = DTRUE;
				
				// Don't stop the sliding sound for at least a little 
				// time after this...
				m_nSlidingFrameCounter = 2;
				bUpdateAgain = DTRUE;
			}
		}

		// Not sliding any more...
		if( !bSlid && m_nSlidingFrameCounter == 0 )
		{
			m_bSliding = DFALSE;
			if( m_hSlidingSound )
			{
				g_pServerDE->KillSound( m_hSlidingSound );
				m_hSlidingSound = DNULL;
			}
		}
		else
		{
			bUpdateAgain = DTRUE;
		}
	}

	// Check if still standing on something...
	if( m_bStandingOn )
	{
		// Check if standing on something...
		g_pServerDE->GetStandingOn( m_hObject, &colInfo );
		if( !colInfo.m_hObject && m_nStandingOnFrameCounter == 0 )
		{
			m_bStandingOn = DFALSE;
		}
	}

	// Adjust the alpha...
	if( fabs( m_fAlpha - m_fTargetAlpha ) > 0.0001f )
	{
		fDeltaTime = fTime - m_fLastTime;
		m_fLastTime = fTime;

		fAlphaAdjust = m_fAlphaFadeRate * fDeltaTime;
		
		// Don't pass the target up...
		if( fabs( fAlphaAdjust ) >= fabs( m_fTargetAlpha - m_fAlpha ))
		{
			m_fAlpha = m_fTargetAlpha;
		}
		else
		{
			m_fAlpha += fAlphaAdjust;
			bUpdateAgain = DTRUE;
		}

		// Set object translucency...
		DVector vTintColor;
		VEC_DIVSCALAR(vTintColor, m_vTintColor, 255.0f);
		g_pServerDE->SetObjectColor(m_hObject, vTintColor.x, vTintColor.y, 
									vTintColor.z, m_fAlpha);

	}

	// Schedule next update...
	if( bUpdateAgain )
	{
		g_pServerDE->SetNextUpdate( m_hObject, 0.001f );
		g_pServerDE->SetDeactivationTime( m_hObject, 1.0f );
	}
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CDestructableModel::TouchNotify
//
//	PURPOSE:	Handles getting touched by something.
//
// ----------------------------------------------------------------------- //

void CDestructableModel::TouchNotify( HOBJECT hObj, DFLOAT fForce )
{
	CollisionInfo colInfo;
	DBOOL bDoUpdate;

	bDoUpdate = DFALSE;

	// If a ai or player is pushing us, and we are on the ground, then
	// start playing a sliding sound...
	if( !m_bSliding && IsBaseCharacter( hObj ))
	{
		m_bSliding = DTRUE;
		m_nSlidingFrameCounter = 2;
		bDoUpdate = DTRUE;
	}

	// Check if standing on something.  If not, then we'll catch that in the update..
	g_pServerDE->GetStandingOn( m_hObject, &colInfo );
	if( fabs( fForce ) > 0.0f && colInfo.m_hObject )
	{
		m_bStandingOn = DTRUE;
		m_nStandingOnFrameCounter = 2;
		bDoUpdate = DTRUE;
	}

	// Schedule next update...
	if( bDoUpdate )
	{
		g_pServerDE->SetNextUpdate( m_hObject, 0.001f );
		g_pServerDE->SetDeactivationTime( m_hObject, 1.0f );
	}
}

// --------------------------------------------------------------------------- //
//
//	ROUTINE:	CDestructableModel::ObjectMessageFn()
//
//	PURPOSE:	Processes a message from a server object.
//
// --------------------------------------------------------------------------- //

DDWORD CDestructableModel::ObjectMessageFn(HOBJECT hSender, DDWORD messageID, HMESSAGEREAD hRead)
{
	CServerDE* pServerDE = GetServerDE();
	switch(messageID)
	{
			
		case MID_DAMAGE:
		{
			DDWORD dwRet = B2BaseClass::ObjectMessageFn(hSender, messageID, hRead);
			HandleDamage();

			return dwRet;

			// Set an update so we can check for damage.
			//pServerDE->SetNextUpdate(m_hObject, 0.001f);
			break;
		}

		case MID_TRIGGER:
		{
			HSTRING hMsg = g_pServerDE->ReadFromMessageHString(hRead);
			char *pMsg = g_pServerDE->GetStringData(hMsg);

			HandleTriggerMessage( pMsg );

			pServerDE->FreeString(hMsg);

			break;
		}
	}

	return B2BaseClass::ObjectMessageFn(hSender, messageID, hRead);
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CDestructableModel::GetSlidingSound
//
//	PURPOSE:	Choose the sliding sound based on the debris type.
//
// ----------------------------------------------------------------------- //

char *CDestructableModel::GetSlidingSound( )
{
	char *pszSlidingSound;

	pszSlidingSound = DNULL;
	switch( m_Debris.GetType( ))
	{
		case SURFTYPE_STONE:
			pszSlidingSound = "sounds\\events\\pushstone.wav";
			break;
		case SURFTYPE_METAL:
			pszSlidingSound = "sounds\\events\\pushmetal.wav";
			break;
		case SURFTYPE_WOOD:
			pszSlidingSound = "sounds\\events\\pushwood.wav";
			break;
		case SURFTYPE_TERRAIN:
			pszSlidingSound = "sounds\\events\\pushterrain.wav";
			break;
		case SURFTYPE_PLASTIC:
			pszSlidingSound = "sounds\\events\\pushplastic.wav";
			break;
		case SURFTYPE_GLASS:
			pszSlidingSound = "sounds\\events\\pushglass.wav";
			break;
		case SURFTYPE_FLESH:
			pszSlidingSound = "sounds\\events\\pushflesh.wav";
			break;
		case SURFTYPE_LIQUID:
			pszSlidingSound = "sounds\\events\\pushliquid.wav";
			break;
		case SURFTYPE_ENERGY:
			pszSlidingSound = "sounds\\events\\pushenergy.wav";
			break;
		default:
			pszSlidingSound = "sounds\\events\\pushwood.wav";
			break;
			
	}

	return pszSlidingSound;
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CDestructableModel::Save
//
//	PURPOSE:	Save the object
//
// ----------------------------------------------------------------------- //

void CDestructableModel::HandleTriggerMessage( char *pMsg )
{
	int nArgs;
    
    char tokenSpace[64*20];
    char *pTokens[64];
    char *pCommand, *pCommandPos;
	DFLOAT fFadeTime;
	DBOOL bMore;

	pCommand = pMsg;
	bMore = DTRUE;
	while( bMore )
	{
		bMore = g_pServerDE->Parse( pMsg, &pCommandPos, tokenSpace, pTokens, &nArgs );

		// Handle the alpha change command...
		if( _mbsicmp((const unsigned char*) pTokens[0], (const unsigned char*)"Alpha" ) == 0 && nArgs > 1 )
		{
			// Get the new alpha value...
			m_fTargetAlpha = ( DFLOAT )atof( pTokens[1] );

			// Get the optional alpha fade time...
			if( nArgs == 3 )
				fFadeTime = ( DFLOAT )atof( pTokens[2] );
			else
				fFadeTime = 0.0f;

			if( fFadeTime > 0.0f )
				m_fAlphaFadeRate = ( m_fTargetAlpha - m_fAlpha ) / fFadeTime;
			else
				m_fAlphaFadeRate = 1.0e10;

			m_fLastTime = g_pServerDE->GetTime( );
			g_pServerDE->SetNextUpdate( m_hObject, 0.01f );
			g_pServerDE->SetDeactivationTime( m_hObject, 1.0f );
		}

		pCommand = pCommandPos;
	}
}

// --------------------------------------------------------------------------- //
//
//	ROUTINE:	CDestructableModel::HandleDamage()
//
//	PURPOSE:	Processes a damage message...
//
// --------------------------------------------------------------------------- //

void CDestructableModel::HandleDamage()
{
	CServerDE* pServerDE = GetServerDE();
	if (!pServerDE) return;

	if (!m_bDeadState && m_bDestructable)
	{
		if (m_damage.GetHitPoints() <= 0)  // m_damage.IsDead())
		{
			// Set next update so we can wait for the cascade delay.
			pServerDE->SetNextUpdate(m_hObject, 0.001f);
//			HandleDestruction();
		}
		else if (m_fDamagedHitPoints > 0 && m_damage.GetHitPoints() <= m_fDamagedHitPoints)
		{
			if (m_hstrDamagedFilename || m_hstrDamagedSkinName)
				pServerDE->SetModelFilenames(m_hObject,
											 pServerDE->GetStringData(m_hstrDamagedFilename), 
											 pServerDE->GetStringData(m_hstrDamagedSkinName));
			DVector vScale;
			VEC_SET( vScale, m_fScale, m_fScale, m_fScale );
			pServerDE->ScaleObject( m_hObject, &vScale );
			if( VEC_MAG( m_DamageDims ) == 0.0f )
			{
				pServerDE->GetModelAnimUserDims(m_hObject, &m_DamageDims, 0);
				VEC_MULSCALAR( m_DamageDims, m_DamageDims, m_fScale );
			}

			pServerDE->SetObjectDims(m_hObject,&m_DamageDims);	//SCHLEGZ: added damaged dims
			// If the object is less than 20x20x20, then turn off shadows, because the 
			// shadows will be visible through model...
			if( VEC_MAGSQR( m_DamageDims ) < 8000.0f )
			{
				DDWORD dwFlags;
				dwFlags = g_pServerDE->GetObjectFlags( m_hObject );
				dwFlags &= ~FLAG_SHADOW;
				g_pServerDE->SetObjectFlags( m_hObject, dwFlags );
			}
			m_fDamagedHitPoints = 0;

			HMESSAGEWRITE hMessage = pServerDE->StartSpecialEffectMessage(this);
			pServerDE->WriteToMessageByte( hMessage, SFX_DESTRUCTABLEMODEL );
			pServerDE->WriteToMessageCompVector( hMessage, &m_DamageDims );
			pServerDE->EndMessage(hMessage);
		}
	}

}



// --------------------------------------------------------------------------- //
//
//	ROUTINE:	CDestructableModel::HandleDestruction()
//
//	PURPOSE:	Handles the object's destruction
//
// --------------------------------------------------------------------------- //

void CDestructableModel::HandleDestruction()
{
	CServerDE* pServerDE = GetServerDE();
	if (!pServerDE) return;

	m_bDeadState = DTRUE;

	// No destroyed filenames, so remove
	if (!m_hstrDestroyFilename && !m_hstrDestroySkinName)
	{
		pServerDE->RemoveObject(m_hObject);
	}
	else
	{
		pServerDE->SetModelFilenames(m_hObject, 
									 pServerDE->GetStringData(m_hstrDestroyFilename), 
									 pServerDE->GetStringData(m_hstrDestroySkinName));
		DVector vScale;
		VEC_SET( vScale, m_fScale, m_fScale, m_fScale );
		pServerDE->ScaleObject( m_hObject, &vScale );
		pServerDE->SetObjectFlags(m_hObject, m_dwDestroyFlags);

		if (VEC_MAG(m_DestroyDims) == 0.0f)
		{
			pServerDE->GetModelAnimUserDims(m_hObject, &m_DestroyDims, 0);
			VEC_MULSCALAR( m_DestroyDims, m_DestroyDims, m_fScale );
		}

		pServerDE->SetObjectDims(m_hObject, &m_DestroyDims);
		// If the object is less than 20x20x20, then turn off shadows, because the 
		// shadows will be visible through model...
		if( VEC_MAGSQR( m_DestroyDims ) < 8000.0f )
		{
			DDWORD dwFlags;
			dwFlags = g_pServerDE->GetObjectFlags( m_hObject );
			dwFlags &= ~FLAG_SHADOW;
			g_pServerDE->SetObjectFlags( m_hObject, dwFlags );
		}

		HMESSAGEWRITE hMessage = pServerDE->StartSpecialEffectMessage(this);
		pServerDE->WriteToMessageByte( hMessage, SFX_DESTRUCTABLEMODEL );
		pServerDE->WriteToMessageCompVector( hMessage, &m_DestroyDims );
		pServerDE->EndMessage(hMessage);
	}
	// Create the debris
	DVector vDir;
	m_damage.GetLastDamageDirection(&vDir);
	m_Debris.Create(vDir, m_damage.GetLastDamageAmount());
}

			
// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CDestructableModel::RotateDims
//
//	PURPOSE:	Try to adjust the dims based on the rotation in m_fYaw
//
// ----------------------------------------------------------------------- //

void CDestructableModel::RotateDims( DRotation *prRot, DVector *pvDims )
{
	DVector vPt[8], vDims;
	DMatrix mMat;
	int i;
	float fVal;

	g_pServerDE->SetupRotationMatrix( &mMat, prRot );

	VEC_SET( vPt[0],  pvDims->x,  pvDims->y,  pvDims->z );
	VEC_SET( vPt[1],  pvDims->x,  pvDims->y, -pvDims->z );
	VEC_SET( vPt[2],  pvDims->x, -pvDims->y,  pvDims->z );
	VEC_SET( vPt[3],  pvDims->x, -pvDims->y, -pvDims->z );
	VEC_SET( vPt[4], -pvDims->x,  pvDims->y,  pvDims->z );
	VEC_SET( vPt[5], -pvDims->x,  pvDims->y, -pvDims->z );
	VEC_SET( vPt[6], -pvDims->x, -pvDims->y,  pvDims->z );
	VEC_SET( vPt[7], -pvDims->x, -pvDims->y, -pvDims->z );

	VEC_INIT( vDims );
	for( i = 0; i < 8; i++ )
	{
		MatVMul_InPlace( &mMat, &vPt[i] );
		fVal = ( float )fabs( vPt[i].x );
		if( vDims.x < fVal )
			vDims.x = fVal;
		fVal = ( float )fabs( vPt[i].y );
		if( vDims.y < fVal )
			vDims.y = fVal;
		fVal = ( float )fabs( vPt[i].z );
		if( vDims.z < fVal )
			vDims.z = fVal;
	}

	VEC_COPY( *pvDims, vDims );
}

	
// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CDestructableModel::Save
//
//	PURPOSE:	Save the object
//
// ----------------------------------------------------------------------- //

void CDestructableModel::Save(HMESSAGEWRITE hWrite, DDWORD dwSaveGame)
{
	CServerDE* pServerDE = GetServerDE();
	if (!pServerDE || !hWrite) return;

	pServerDE->WriteToMessageHString(hWrite, m_hstrDamagedFilename);
	pServerDE->WriteToMessageHString(hWrite, m_hstrDamagedSkinName);
	pServerDE->WriteToMessageHString(hWrite, m_hstrDestroyFilename);
	pServerDE->WriteToMessageHString(hWrite, m_hstrDestroySkinName);

	pServerDE->WriteToMessageVector(hWrite, &m_InitDims);
	pServerDE->WriteToMessageVector(hWrite, &m_DamageDims);
	pServerDE->WriteToMessageVector(hWrite, &m_DestroyDims);

	pServerDE->WriteToMessageDWord(hWrite, m_dwDestroyFlags);
	pServerDE->WriteToMessageByte(hWrite, m_bDeadState);
	pServerDE->WriteToMessageFloat(hWrite, m_fInitHitPoints);
	pServerDE->WriteToMessageFloat(hWrite, m_fDamagedHitPoints);
	pServerDE->WriteToMessageFloat(hWrite, m_fMass);
	pServerDE->WriteToMessageFloat(hWrite, m_fAlpha);
	pServerDE->WriteToMessageFloat(hWrite, m_fYaw);

	pServerDE->WriteToMessageByte(hWrite, m_bDestroyVisible);
	pServerDE->WriteToMessageByte(hWrite, m_bDestroySolid);
	pServerDE->WriteToMessageByte(hWrite, m_bDestroyGravity);
	pServerDE->WriteToMessageByte(hWrite, m_bDestructable);
	pServerDE->WriteToMessageByte(hWrite, m_bPushable);
	pServerDE->WriteToMessageDWord(hWrite, m_dwSurfType);

	pServerDE->WriteToMessageByte(hWrite, m_bChrome);
	pServerDE->WriteToMessageFloat( hWrite, m_fScale );
	pServerDE->WriteToMessageVector(hWrite, &m_vTintColor);
	pServerDE->WriteToMessageFloat(hWrite, m_fTargetAlpha);
	pServerDE->WriteToMessageFloat(hWrite, m_fAlphaFadeRate);
	pServerDE->WriteToMessageFloat(hWrite, m_fLastTime);
	pServerDE->WriteToMessageHString(hWrite, m_hstrSlidingSound);
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CDestructableModel::Load
//
//	PURPOSE:	Load the object
//
// ----------------------------------------------------------------------- //

void CDestructableModel::Load(HMESSAGEREAD hRead, DDWORD dwLoadGame)
{
	CServerDE* pServerDE = GetServerDE();
	if (!pServerDE || !hRead) return;

	m_hstrDamagedFilename	= pServerDE->ReadFromMessageHString(hRead);
	m_hstrDamagedSkinName	= pServerDE->ReadFromMessageHString(hRead);
	m_hstrDestroyFilename	= pServerDE->ReadFromMessageHString(hRead);
	m_hstrDestroySkinName	= pServerDE->ReadFromMessageHString(hRead);

	pServerDE->ReadFromMessageVector(hRead, &m_InitDims);
	pServerDE->ReadFromMessageVector(hRead, &m_DamageDims);
	pServerDE->ReadFromMessageVector(hRead, &m_DestroyDims);
	m_dwDestroyFlags		= pServerDE->ReadFromMessageDWord(hRead);
	m_bDeadState			= pServerDE->ReadFromMessageByte(hRead);
	m_fInitHitPoints		= pServerDE->ReadFromMessageFloat(hRead);
	m_fDamagedHitPoints		= pServerDE->ReadFromMessageFloat(hRead);
	m_fMass					= pServerDE->ReadFromMessageFloat(hRead);
	m_fAlpha				= pServerDE->ReadFromMessageFloat(hRead);
	m_fYaw					= pServerDE->ReadFromMessageFloat(hRead);

	m_bDestroyVisible		= pServerDE->ReadFromMessageByte(hRead);
	m_bDestroySolid			= pServerDE->ReadFromMessageByte(hRead);
	m_bDestroyGravity		= pServerDE->ReadFromMessageByte(hRead);
	m_bDestructable			= pServerDE->ReadFromMessageByte(hRead);
	m_bPushable				= pServerDE->ReadFromMessageByte(hRead);
	m_dwSurfType			= pServerDE->ReadFromMessageDWord(hRead);

	m_bChrome				= pServerDE->ReadFromMessageByte(hRead);
	m_fScale				= pServerDE->ReadFromMessageFloat( hRead );
	pServerDE->ReadFromMessageVector(hRead, &m_vTintColor);

	m_fTargetAlpha			= pServerDE->ReadFromMessageFloat(hRead);
	m_fAlphaFadeRate		= pServerDE->ReadFromMessageFloat(hRead);
	m_fLastTime				= pServerDE->ReadFromMessageFloat(hRead);
	m_hstrSlidingSound		= pServerDE->ReadFromMessageHString(hRead);
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -