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

📄 gameprojectiles.cpp

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

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CGasGrenade::DamageAndWonky()
//
//	PURPOSE:	Damage people in the gas and give them wonky vision
//
// ----------------------------------------------------------------------- //

void CGasGrenade::DamageAndWonky(DFLOAT fWonkyTime)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE)	return;

	// Get the head of the list of destructable objects
	DLink*	pLink = CDestructable::m_DestructableHead.m_pNext;
	if(!pLink || (pLink == &CDestructable::m_DestructableHead))	return;

	HOBJECT		hObj;
	HCLASS		hCharacter	= pServerDE->GetClass("CBaseCharacter");
	HCLASS		hPlayer		= pServerDE->GetClass("CPlayerObj");
	HCLASS		hObjClass   = DNULL;

	// Get a forward vector and position of the player who shot the voodoo doll
	DVector		vGrenadePos;
	pServerDE->GetObjectPos(m_hObject, &vGrenadePos);

	// Go through the list of destructable objects and look for people within your FOV
	while(pLink != &CDestructable::m_DestructableHead)
	{
		hObj = ((CDestructable*)pLink->m_pData)->GetObject();
		if(!hObj)	break;
		hObjClass = pServerDE->GetObjectClass(hObj);

		if(pServerDE->IsKindOf(hObjClass, hCharacter))
		{
			DVector		vObjPos, vDir;
			DFLOAT		fDist, fNewDamage;

			// Test the angle between this object and us
			pServerDE->GetObjectPos(hObj, &vObjPos);
			VEC_SUB(vDir, vObjPos, vGrenadePos);
			fDist = VEC_MAG(vDir);

			// If the target is too far away... skip it
			if(fDist > GAS_GRENADE_DAMAGE_DIST)
				{ pLink = pLink->m_pNext; continue; }

			fNewDamage = GAS_GRENADE_MAX_DAMAGE - (GAS_GRENADE_MAX_DAMAGE * (fDist / GAS_GRENADE_DAMAGE_DIST));

			DamageObject(m_hFiredFrom, this, hObj, fNewDamage, vDir, vObjPos, DAMAGE_TYPE_NORMAL);

			if(pServerDE->IsKindOf(hObjClass, hPlayer))
			{
		    	CPlayerObj *pHit = (CPlayerObj*)pServerDE->HandleToObject(hObj);

				HMESSAGEWRITE hMsg = pServerDE->StartMessage(pHit->GetClient(), SMSG_WONKYVISION);
				pServerDE->WriteToMessageFloat(hMsg, fWonkyTime);
				pServerDE->WriteToMessageByte(hMsg, 0);	// bNoMove = DFALSE
				pServerDE->EndMessage2(hMsg, MESSAGE_GUARANTEED | MESSAGE_NAGGLE);
			}
		}

		pLink = pLink->m_pNext;
	}
}

#endif

#ifndef _DEMO

BEGIN_CLASS(CTimeBomb)
END_CLASS_DEFAULT_FLAGS(CTimeBomb, CProjectile, NULL, NULL, CF_HIDDEN)

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CTimeBomb::CTimeBomb()
//
//	PURPOSE:	Constructor
//
// ----------------------------------------------------------------------- //

CTimeBomb::CTimeBomb() : CProjectile()
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE) return;

	m_bShockwave			= DFALSE;
	m_bExplosion			= DTRUE;

	m_pProjectileFilename	= "Models\\Ammo\\c4.abc";
	m_pProjectileSkin		= "Skins\\Ammo\\c4_time.dtx";

	m_nDamageType			= DAMAGE_TYPE_EXPLODE;

	m_dwFlags				= m_dwFlags | FLAG_GRAVITY;
	m_bArmed				= DFALSE;
	m_bExplode				= DFALSE;
	m_fStartTime			= 0.0f;
	m_fTimeDelay			= 5.0f;

	// Set up angular velocities
	m_fPitch				= 0.0f;
	m_fYaw					= 0.0f;
	m_fPitchVel				= pServerDE->Random(-MATH_CIRCLE, MATH_CIRCLE);
	m_fYawVel				= pServerDE->Random(-MATH_CIRCLE, MATH_CIRCLE);

	m_damage.SetDeathDelay(0.25f);		// .25 second delay if killed by explosion
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CTimeBomb::Update()
//
//	PURPOSE:	Do update
//
// ----------------------------------------------------------------------- //

DBOOL CTimeBomb::Update(DVector *pMovement)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE) return DFALSE;

	pServerDE->SetNextUpdate(m_hObject, (DFLOAT)0.001);
	DFLOAT fTime = pServerDE->GetTime();

	pServerDE->GetObjectPos(m_hObject, &m_LastPos);

	if(m_bExplode || m_damage.IsDead())
	{
		Explode();
		return DFALSE;
	}

	if(m_bArmed)
	{
		DVector		vVel;
		VEC_INIT(vVel);
		pServerDE->SetVelocity(m_hObject, &vVel);

		// Count down to explode time
		if (fTime > m_fStartTime + m_fTimeDelay)
			m_bExplode = DTRUE;
	}
	else
	{
		DRotation rRot;
		pServerDE->GetObjectRotation(m_hObject, &rRot);

		// Rotate the object as it flys through the air
		if (m_fPitchVel != 0 || m_fYawVel != 0)
		{
			DFLOAT fDeltaTime = pServerDE->GetFrameTime();

			m_fPitch += m_fPitchVel * fDeltaTime;
			m_fYaw += m_fYawVel * fDeltaTime;

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

	return DTRUE;
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CTimeBomb::HandleTouch()
//
//	PURPOSE:	Handle touch notify message
//
// ----------------------------------------------------------------------- //

void CTimeBomb::HandleTouch(HOBJECT hObj)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE) return;

	if(m_bArmed)
		return;

	if(hObj == m_hFiredFrom)
		return;

	if(hObj != pServerDE->GetWorldObject() && !(pServerDE->GetObjectFlags(hObj) & FLAG_SOLID))
		return;

	if (pServerDE->IsKindOf(pServerDE->GetObjectClass(hObj), pServerDE->GetClass("CBaseCharacter")))
	{
		CBaseCharacter *pObj = (CBaseCharacter*)pServerDE->HandleToObject(hObj);
		if(pObj->IsDead())	return;

		CProjectile::HandleTouch(hObj);	// Explode on impact type.
	}
	else
	{
		CollisionInfo colInfo;
		pServerDE->GetLastCollision( &colInfo );

		DVector		vU, vR, vF;
		DRotation	rRot;

		VEC_SET(vU, 0.0f, 1.0f, 0.0f);

		pServerDE->AlignRotation(&rRot, &colInfo.m_Plane.m_Normal, &vU);
		pServerDE->GetRotationVectors(&rRot, &vU, &vR, &vF);
		pServerDE->RotateAroundAxis(&rRot, &vR, MATH_PI * 0.5f);
		pServerDE->SetObjectRotation(m_hObject, &rRot);

		DDWORD	dwFlags = pServerDE->GetObjectFlags(m_hObject);
		dwFlags &= ~FLAG_GRAVITY;
		pServerDE->SetObjectFlags(m_hObject, dwFlags);

		m_bArmed = DTRUE;
		m_fStartTime = pServerDE->GetTime();
	}
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CTimeBomb::AddExplosion()
//
//	PURPOSE:	Add an explosion
//
// ----------------------------------------------------------------------- //

void CTimeBomb::AddExplosion(DVector vPos, DVector vNormal)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE) return;

	DDWORD		nType = EXP_DEFAULT_SMALL;

	HMESSAGEWRITE hMessage = pServerDE->StartInstantSpecialEffectMessage(&vPos);
	pServerDE->WriteToMessageByte(hMessage, SFX_EXPLOSIONFX_ID);

	pServerDE->WriteToMessageVector(hMessage, &vPos);
	pServerDE->WriteToMessageVector(hMessage, &vNormal);
	pServerDE->WriteToMessageDWord(hMessage, nType);

	pServerDE->EndMessage2(hMessage, MESSAGE_GUARANTEED);

	PlaySoundFromPos(&vPos, "Sounds\\Weapons\\time\\explode.wav", 1000.0f, SOUNDPRIORITY_MISC_MEDIUM);
}




BEGIN_CLASS(CProximityBomb)
END_CLASS_DEFAULT_FLAGS(CProximityBomb, CProjectile, NULL, NULL, CF_HIDDEN)

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CProximityBomb::CProximityBomb()
//
//	PURPOSE:	Constructor
//
// ----------------------------------------------------------------------- //

CProximityBomb::CProximityBomb() : CProjectile()
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE) return;

	m_bShockwave			= DFALSE;
	m_bExplosion			= DTRUE;

	m_pProjectileFilename	= "Models\\Ammo\\c4.abc";
	m_pProjectileSkin		= "Skins\\Ammo\\c4_prox.dtx";

	m_nDamageType			= DAMAGE_TYPE_EXPLODE;

	m_dwFlags				= m_dwFlags | FLAG_GRAVITY;
	m_bArmed				= DFALSE;
	m_bExplode				= DFALSE;
	m_fStartTime			= 0.0f;

	m_fDetectRadius			= 225.0f;
	m_fGetAwayTime			= 0.75f;
	m_fExplodeDelay			= 0.5f;
	m_bHitCharacter			= DFALSE;
	m_bPlayArmSound			= DTRUE;
	m_bPlayDetectSound		= DTRUE;

	// Set up angular velocities
	m_fPitch				= 0.0f;
	m_fYaw					= 0.0f;
	m_fPitchVel				= pServerDE->Random(-MATH_CIRCLE, MATH_CIRCLE);
	m_fYawVel				= pServerDE->Random(-MATH_CIRCLE, MATH_CIRCLE);

	m_damage.SetDeathDelay(0.25f);		// .25 second delay if killed by explosion
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CProximityBomb::Update()
//
//	PURPOSE:	Do update
//
// ----------------------------------------------------------------------- //

DBOOL CProximityBomb::Update(DVector *pMovement)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE) return DFALSE;

	pServerDE->SetNextUpdate(m_hObject, (DFLOAT)0.001);
	DFLOAT fTime = pServerDE->GetTime();

	pServerDE->GetObjectPos(m_hObject, &m_LastPos);

	if(m_bExplode || m_damage.IsDead())
	{
		if(!m_bHitCharacter && (pServerDE->GetTime() < m_fStartTime + m_fExplodeDelay) && !m_damage.IsDead())
		{
			if(m_bPlayDetectSound)
			{
				PlaySoundFromPos(&m_LastPos, "Sounds\\Weapons\\proximities\\detect.wav", 500.0f, SOUNDPRIORITY_MISC_MEDIUM);
				m_bPlayDetectSound = DFALSE;
			}

			return DTRUE;
		}
		else
		{
			Explode();
			return DFALSE;
		}
	}

	if(m_bArmed)
	{
		DVector		vVel;
		VEC_INIT(vVel);
		pServerDE->SetVelocity(m_hObject, &vVel);

		if(m_hFiredFrom)
		{
			HCLASS hClass = pServerDE->GetObjectClass(m_hFiredFrom);
			if(pServerDE->IsKindOf(hClass, pServerDE->GetClass("AI_Mgr")))
				m_fGetAwayTime = 2.0f;
		}

		// Wait a little while before going into detect mode
		if(pServerDE->GetTime() < m_fStartTime + m_fGetAwayTime)
			return DTRUE;
		else if(m_bPlayArmSound)
		{
			PlaySoundFromPos(&m_LastPos, "Sounds\\Weapons\\proximities\\arm.wav", 500.0f, SOUNDPRIORITY_MISC_MEDIUM);
			m_bPlayArmSound = DFALSE;
		}

		// Check to see if there's anyone in our radius of detection, then blow up

		// Get the head of the list of destructable objects
		DLink*	pLink = CDestructable::m_DestructableHead.m_pNext;
		if(!pLink || (pLink == &CDestructable::m_DestructableHead))	return DTRUE;

		// Work with the squares of the distances so as to not have to get a square root.
		HOBJECT		hObj;
		DVector		vProxPos;
		DFLOAT		fRadiusSqr		= m_fDetectRadius * m_fDetectRadius;

		pServerDE->GetObjectPos(m_hObject, &vProxPos);

		while(pLink != &CDestructable::m_DestructableHead)
		{
			hObj = ((CDestructable*)pLink->m_pData)->GetObject();
			if(!hObj)	break;

			if(pServerDE->IsKindOf(pServerDE->GetObjectClass(hObj), pServerDE->GetClass("CBaseCharacter")))
			{
				CBaseCharacter *pObj = (CBaseCharacter*)pServerDE->HandleToObject(hObj);

				if(!pObj->IsDead())
				{
					DVector		vDir, vPos;
					DFLOAT		fDistSqr;

					pServerDE->GetObjectPos(hObj, &vPos);
					VEC_SUB(vDir, vPos, vProxPos);

					fDistSqr = VEC_MAGSQR(vDir);
					if(fDistSqr <= fRadiusSqr)
					{
						m_bExplode = DTRUE;
						m_fStartTime = pServerDE->GetTime();
						break;
					}
				}
			}

			pLink = pLink->m_pNext;
		}
	}
	else
	{
		DRotation rRot;
		pServerDE->GetObjectRotation(m_hObject, &rRot);

		// Rotate the object as it flys through the air
		if (m_fPitchVel != 0 || m_fYawVel != 0)
		{
			DFLOAT fDeltaTime = pServerDE->GetFrameTime();

			m_fPitch += m_fPitchVel * fDeltaTime;
			m_fYaw += m_fYawVel * fDeltaTime;

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

	return DTRUE;
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CProximityBomb::HandleTouch()
//
//	PURPOSE:	Handle touch notify message
//
// ----------------------------------------------------------------------- //

void CProximityBomb::HandleTouch(HOBJECT hObj)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if(!pServerDE) return;

	if(m_bArmed)
		return;

	if(hObj == m_hFiredFrom)
		return;

	if(hObj != pServerDE->GetWorldObject() && !(pServerDE->GetObjectFlags(hObj) & FLAG_SOLID))
		return;

	if(pServerDE->IsKindOf(pServerDE->GetObjectClass(hObj), pServerDE->GetClass("CBaseCharacter")))
	{
		CBaseCharacter *pObj = (CBaseCharacter*)pServerDE->HandleToObject(hObj);
		if(pObj->IsDead())	return;

		CProjectile::HandleTouch(hObj);	// Explode on impact type.
		m_bHitCharacter = DTRUE;
	}
	else
	{
		CollisionInfo colInfo;
		pServerDE->GetLastCollision( &colInfo );

		DVector		vU, vR, vF;
		DRotation	rRot;

		VEC_SET(vU, 0.0f, 1.0f, 0.0f);

		pServerDE->AlignRotation(&rRot, &colInfo.m_Plane.m_Normal, &vU);
		pServerDE->GetRotationVectors(&rRot, &vU, &vR, &vF);
		pServerDE->RotateAroundAxis(&rRot, &vR, MATH_PI * 0.5f);
		pServerDE->SetObjectRotation(m_hObject, &rRot);

		DDWORD	dwFlags = pServerDE->GetObjectFlags(m_hObject);

⌨️ 快捷键说明

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