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

📄 gib.cpp

📁 Blood 2全套源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		if (hClass)
		{
			pTrail = (CClientSmokeTrail*)pServerDE->CreateObject(hClass, &theStruct);
		}

		if (pTrail)
		{
			DVector vVel;
			pServerDE->GetVelocity(m_hObject, &vVel);
			pTrail->Setup(vVel, DFALSE);
			m_hSmokeTrail = pTrail->m_hObject;
		}
	}
/*
	if (m_bAddBloodTrail)
	{
		ObjectCreateStruct theStruct;
		INIT_OBJECTCREATESTRUCT(theStruct);

		pServerDE->GetObjectPos(m_hObject, &theStruct.m_Pos);
		HCLASS hClass = pServerDE->GetClass("CClientBloodTrail");

		CClientBloodTrail* pTrail = DNULL;

		if (hClass)
		{
			pTrail = (CClientBloodTrail*)pServerDE->CreateObject(hClass, &theStruct);
		}

		if (pTrail)
		{
			DVector vVel,vColor;
			VEC_SET(vColor,200.0f,0.0f,0.0f);

			pServerDE->GetVelocity(m_hObject, &vVel);
			pTrail->Setup(vVel, vColor);
			m_hBloodTrail = pTrail->m_hObject;
		}
	}
*/	
	if (m_dwSurfType)
	{
		DDWORD dwFlags = g_pServerDE->GetObjectUserFlags(m_hObject);
		dwFlags |= (m_dwSurfType << 24);
		g_pServerDE->SetObjectUserFlags(m_hObject,dwFlags);
	}

	if(m_dwGibType & GIB_CORPSE)	//so the corpse does not initially make a noise
		m_bPlaySplat = DTRUE;

	if (g_pBloodServerShell->IsMultiplayerGame())
	{
		m_fRemoveTime = g_pServerDE->GetTime() + GIB_REMOVETIME - 0.1f;
	}
	//scale the object down if small
	pServerDE->SetNextUpdate( m_hObject, 0.1f );
	pServerDE->SetDeactivationTime( m_hObject, 1.0f );
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CGib::Update
//
//	PURPOSE:
//
// ----------------------------------------------------------------------- //

DBOOL CGib::Update()
{
	CServerDE* pServerDE = GetServerDE();
	if (!pServerDE) return DFALSE;

	DVector vVel;
	DRotation rRot;

	DFLOAT fTime = pServerDE->GetTime();
	if (m_fRemoveTime && m_fRemoveTime < fTime) return DFALSE;

	if (m_bFirstUpdate)
	{
		// If any dim are significantly smaller than the others, set alignment so it'll come to 
		// rest aligned correctly.
		DVector vDims;
		pServerDE->GetObjectDims(m_hObject, &vDims);
		if (vDims.y < vDims.x * 0.7f)
			m_nAxisAlign = 2;
		if (vDims.x < vDims.y * 0.7f)
			m_nAxisAlign = 1;
		if (vDims.z < vDims.y * 0.7f)
			m_nAxisAlign = 3;

		m_bFirstUpdate = DFALSE;
	}

	pServerDE->GetObjectPos(m_hObject, &m_vLastPos);
	pServerDE->GetObjectRotation( m_hObject, &rRot );
	pServerDE->GetVelocity( m_hObject ,&vVel );


	if (m_bAddBloodSpurt && m_dwSurfType == SURFTYPE_FLESH)
	{
		DVector vSpurtVel;
		VEC_MULSCALAR(vSpurtVel, vVel, 0.1f);
		HMESSAGEWRITE hMessage = g_pServerDE->StartInstantSpecialEffectMessage(&m_vLastPos);
		g_pServerDE->WriteToMessageByte(hMessage, SFX_PARTICLEEXPLOSION_ID);
		g_pServerDE->WriteToMessageVector(hMessage, &m_vLastPos);
		g_pServerDE->WriteToMessageCompVector(hMessage, &vSpurtVel);
		g_pServerDE->EndMessage(hMessage);

		m_bAddBloodSpurt = DFALSE;
	}


	if(m_hSmokeTrail)
		pServerDE->SetObjectPos(m_hSmokeTrail, &m_vLastPos);

	if(m_hBloodTrail)
		pServerDE->SetObjectPos(m_hBloodTrail, &m_vLastPos);

	m_fRotateTime -= pServerDE->GetFrameTime();

	// If velocity slows enough, stop moving
	if (VEC_MAGSQR(vVel) <= 50.0 || m_fRotateTime <= 0.0f)
	{
		if(m_hSmokeTrail)
		{
			pServerDE->RemoveObject(m_hSmokeTrail);
			m_hSmokeTrail = DNULL;
		}

		if(m_hBloodTrail)
		{
			pServerDE->RemoveObject(m_hBloodTrail);
			m_hBloodTrail = DNULL;
		}

		m_fPitchVel = 0;
		m_fYawVel	= 0;
		m_fRollVel	= 0;

		// Align so that y axis is either straight up or down
		switch(m_nAxisAlign)
		{
			case 1:		// Yaw
			{
				m_fYaw = (m_fYaw > MATH_HALFPI && m_fYaw < MATH_HALFPI + MATH_PI) ? MATH_PI : 0;
			}
			break;

			case 2:		// Pitch
			{
				m_fPitch = (m_fPitch > MATH_HALFPI && m_fPitch < MATH_HALFPI + MATH_PI) ? MATH_PI : 0;
			}
			break;

			case 3:		// Roll
			{
				m_fRoll = (m_fRoll > MATH_HALFPI && m_fRoll < MATH_HALFPI + MATH_PI) ? MATH_PI : 0;
			}
			break;
		}

		pServerDE->SetupEuler(&rRot, m_fPitch, m_fYaw, m_fRoll);
		pServerDE->SetObjectRotation(m_hObject, &rRot);	

		if (g_pBloodServerShell->IsMultiplayerGame())
			pServerDE->SetNextUpdate( m_hObject, 0.01f );
		else
			pServerDE->SetNextUpdate( m_hObject, 0.0f );
	}
	else
	{
		if (m_fPitchVel != 0 || m_fYawVel != 0 || m_fRollVel != 0)
		{
			DFLOAT fDeltaTime = pServerDE->GetFrameTime();

			m_fPitch += m_fPitchVel * fDeltaTime;
			if (m_fPitch > MATH_CIRCLE) m_fPitch -= MATH_CIRCLE;

			m_fYaw += m_fYawVel * fDeltaTime;
			if (m_fYaw > MATH_CIRCLE) m_fYaw -= MATH_CIRCLE;

			m_fRoll += m_fRollVel * fDeltaTime;
			if (m_fRoll > MATH_CIRCLE) m_fRoll -= MATH_CIRCLE;

			pServerDE->SetupEuler(&rRot, m_fPitch, m_fYaw, m_fRoll);
			pServerDE->SetObjectRotation(m_hObject, &rRot);	
		}

		pServerDE->SetNextUpdate( m_hObject, 0.01f );
	}

	pServerDE->SetDeactivationTime( m_hObject, 1.0f );
	return DTRUE;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CGib::HandleTouch
//
//	PURPOSE:
//
// ----------------------------------------------------------------------- //

void CGib::HandleTouch(HOBJECT hObj, DFLOAT fData)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE) return;


	DVector vPos;
	pServerDE->GetObjectPos(m_hObject, &vPos);

	// See if it should kick high..
	if (m_bKickable && IsBaseCharacter(hObj))
	{
		DVector vVel;
		pServerDE->GetVelocity(hObj, &vVel);

		if (VEC_MAGSQR(vVel) > 25.0f)
		{
			vVel.y += 300.0f;
			VEC_MULSCALAR(vVel, vVel, 2.0f);
			pServerDE->SetVelocity(m_hObject, &vVel);
			m_nBounceCount = 2;
			m_fPitchVel = pServerDE->Random(-MATH_CIRCLE, MATH_CIRCLE) / 3.0f;
			m_fYawVel	= pServerDE->Random(-MATH_CIRCLE, MATH_CIRCLE) / 3.0f;
			m_fRollVel	= pServerDE->Random(-MATH_CIRCLE, MATH_CIRCLE) / 3.0f;
			PlayBounceSound();
			if (m_dwSurfType == SURFTYPE_FLESH)
			{
				VEC_MULSCALAR(vVel, vVel, 0.02f);
				HMESSAGEWRITE hMessage = g_pServerDE->StartInstantSpecialEffectMessage(&vPos);
				g_pServerDE->WriteToMessageByte(hMessage, SFX_PARTICLEEXPLOSION_ID);
				g_pServerDE->WriteToMessageVector(hMessage, &vPos);
				g_pServerDE->WriteToMessageCompVector(hMessage, &vVel);
				g_pServerDE->EndMessage(hMessage);
			}

			m_fRotateTime = 1.0f;
			pServerDE->SetNextUpdate( m_hObject, 0.01f );
			return;
		}
	}

	// return if it hit a non solid object
	if (hObj != pServerDE->GetWorldObject() && !(pServerDE->GetObjectFlags(hObj) & FLAG_SOLID)) // Ignore non-solid objects
		return;

 	// Cast a ray from our last known position to see what we hit
	IntersectQuery iq;
	IntersectInfo  ii;
	DVector vVel;

	pServerDE->GetVelocity(m_hObject, &vVel);

    // If velocity is small then do not Cast segment...
    if ( ((int)vVel.x+(int)vVel.z) == 0 || ((int)vVel.x+(int)vVel.z) == -0 || --m_nBounceCount < 0)
    {
        return;
    }

	VEC_COPY(iq.m_From, m_vLastPos);			// Get start point at the last known position.
	VEC_MULSCALAR(iq.m_To, vVel, 1.1f);
	VEC_ADD(iq.m_To, iq.m_To, iq.m_From);	// Get destination point slightly past where we should be
	iq.m_Flags = INTERSECT_OBJECTS | IGNORE_NONSOLID;
	iq.m_FilterFn = NULL;
	iq.m_pUserData = NULL;	

	// Hit something!
	if (pServerDE->IntersectSegment(&iq, &ii))
	{
    
		// Compute new velocity reflected off of the surface.
		DVector vNormal;
		VEC_COPY(vNormal, ii.m_Plane.m_Normal);

		DFLOAT r = VEC_DOT(vVel, vNormal);
		
		r *= 0.3f;

		if (r > -100.0f) 
			r = 0;
		else
		{
			PlayBounceSound();

			VEC_MULSCALAR(vNormal, vNormal, r);
			VEC_SUB(vVel, vVel, vNormal);

			// Adjust the bouncing..
			m_fPitchVel = pServerDE->Random(-MATH_CIRCLE, MATH_CIRCLE) / 3.0f;
			m_fYawVel	= pServerDE->Random(-MATH_CIRCLE, MATH_CIRCLE) / 3.0f;
			m_fRollVel	= pServerDE->Random(-MATH_CIRCLE, MATH_CIRCLE) / 3.0f;
		}

		VEC_MULSCALAR(vVel, vVel, 0.5f);	// Lose some energy in the bounce.
		pServerDE->SetVelocity(m_hObject, &vVel);

		m_fRotateTime = 1.0f;
		m_bAddBloodSpurt = DTRUE;
		pServerDE->SetNextUpdate( m_hObject, 0.01f );
	}

	return;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CGib::PlayBounceSound()
//
//	PURPOSE:
//
// ----------------------------------------------------------------------- //

void CGib::PlayBounceSound()
{
	// Play a bounce sound...
	char szSound[MAX_CS_FILENAME_LEN+1];

	switch(m_dwSurfType)
	{
		case SURFTYPE_FLESH:
		{
			int index = GetRandom(1, NRES(5));
			sprintf(szSound, "sounds\\gibs\\flesh\\gib_impact%d.wav", index);
			break;
		}
		case SURFTYPE_PLASTIC:
		{
			sprintf(szSound, "sounds\\bounce\\pylon.wav");
			break;
		}
	}

	PlaySoundFromObject(m_hObject, szSound, 1000, SOUNDPRIORITY_MISC_LOW);
}

	
// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CGib::Damage()
//
//	PURPOSE:
//
// ----------------------------------------------------------------------- //

void CGib::Damage(DVector vDir)
{
	//if the gib is destroyed, create more possible
	if(m_damage.IsDead())
	{
		if(!m_bGibbed && !(m_dwGibType & GIB_SMALL) && !(m_dwGibType & GIB_FLESH))
		{
			if(m_dwGibType & GIB_CORPSE)
			{
				m_dwGibType = m_dwGibType ^ GIB_CORPSE;
				m_dwGibType |= GIB_FLESH;
			}
			else
				m_dwGibType |= GIB_SMALL;

			CreateGibs(m_hObject,m_dwGibType,m_damage.GetLastDamageType(),vDir, (int)m_fMass);
			m_bGibbed = DTRUE;
		}

		g_pServerDE->RemoveObject( m_hObject );
	}	

	return;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CGib::CreateGibs()
//
//	PURPOSE:	Create more gibs
//
// ----------------------------------------------------------------------- //

void CGib::CreateGibs(HOBJECT hObject, DDWORD dwGibType, DBYTE dmgType, DVector vDmgDir, int nNumDebris)
{
	CServerDE* g_pServerDE = GetServerDE();

	int nItem;
	HCLASS hClass;
	DVector vPos, vVel, vParentDims;
	DRotation rRot;

	hClass = g_pServerDE->GetClass( "CGib" );
	if( !hClass )
		return;

	g_pServerDE->GetObjectPos( hObject, &vPos );
	g_pServerDE->GetObjectRotation( hObject, &rRot );

	// Get dims of this prop...
	g_pServerDE->GetObjectDims( hObject, &vParentDims );

	// Make the debris...
	for( nItem = 0; nItem < nNumDebris; nItem++ )
	{
		ObjectCreateStruct theStruct;
		INIT_OBJECTCREATESTRUCT(theStruct);

		theStruct.m_Flags = FLAG_VISIBLE | FLAG_RAYHIT | FLAG_GRAVITY | FLAG_TOUCH_NOTIFY;

		theStruct.m_UserData = dwGibType;
		if (dmgType == DAMAGE_TYPE_EXPLODE)
			theStruct.m_UserData |= GIB_SMOKETRAIL;

		if(dwGibType & GIB_FLESH)
			theStruct.m_UserData |= GIB_BLOODTRAIL;
			
		VEC_SET( theStruct.m_Pos, GetServerDE()->Random( -vParentDims.x, vParentDims.x ), GetServerDE()->Random( 0.1f, vParentDims.y ), 
			GetServerDE()->Random( -vParentDims.z, vParentDims.z ));
		VEC_ADD( theStruct.m_Pos, theStruct.m_Pos, vPos );

		// Make sure the velocity is somewhat upward...
		vVel.x = vDmgDir.x * g_pServerDE->Random(0.0f, 300.0f);
		vVel.y = g_pServerDE->Random(0.0f, 400.0f);
		vVel.z = vDmgDir.z * g_pServerDE->Random(0.0f, 300.0f);

		//Copy the rotation vector
		ROT_COPY(theStruct.m_Rotation,rRot);

		// Allocate an object...
		BaseClass* pObj = g_pServerDE->CreateObject( hClass, &theStruct );
		if( !pObj )
			break;

		// Randomly scale
		DVector vScale;
		vScale.x = (DFLOAT)g_pServerDE->Random(0.8f,1.2f);
		vScale.y = (DFLOAT)g_pServerDE->Random(0.8f,1.2f);
		vScale.z = (DFLOAT)g_pServerDE->Random(0.8f,1.2f);
		
		if(dwGibType & GIB_SMALL)
		{
			VEC_MULSCALAR(vScale,vScale,0.4f);
		}
		else
		{
			VEC_MULSCALAR(vScale,vScale,1.0f);
		}

		g_pServerDE->ScaleObject(pObj->m_hObject, &vScale);

		g_pServerDE->SetVelocity( pObj->m_hObject, &vVel );
	}
}



⌨️ 快捷键说明

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