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

📄 gameprojectiles.cpp

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

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

	DVector		vScale, vVel, vPos;
	DFLOAT		fTime = pServerDE->GetTime();

	pServerDE->SetNextUpdate(m_hObject, (DFLOAT)0.001);

	VEC_SET(vScale, 0.25f, 0.25f, 0.25f);
	pServerDE->ScaleObject(m_hObject, &vScale);

	if(m_nBounces >= 3)
		return DFALSE;

	if(m_bExplode)
	{
		Explode();
		m_bExplode = DFALSE;
	}

	pServerDE->GetVelocity(m_hObject, &vVel);
	pServerDE->GetObjectPos(m_hObject, &vPos);

	if (m_hLight)
		pServerDE->SetObjectPos(m_hLight, &vPos);

	return DTRUE;
}


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

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

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

	// return if it hit another of this same class
	if (pServerDE->GetObjectClass(hObj) == pServerDE->GetObjectClass(m_hObject))
		return;

	m_nBounces++;

	m_bExplode = DTRUE;
	m_hHitObject = hObj;

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

	pServerDE->GetVelocity(m_hObject, &vVel);
	VEC_COPY(vLift, vVel);
	pServerDE->GetObjectPos(m_hObject, &m_LastPos);

	VEC_COPY(iq.m_From, m_LastPos);			// 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;	

	if(pServerDE->IntersectSegment(&iq, &ii))
	{
		VEC_MULSCALAR(vVel, vVel, 0.35f);
		pServerDE->SetVelocity(m_hObject, &vVel);
	}
}


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

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

	DDWORD		nType = EXP_NAPALM_FIREBALL;

	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\\c4\\explosion_1.wav", 1000.0f, SOUNDTYPE_MISC, SOUNDPRIORITY_MEDIUM);
}



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

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

CBugSprayProjectile::CBugSprayProjectile() : CProjectile(OT_SPRITE)
{
	m_bShockwave			= DFALSE;
	m_bExplosion			= DTRUE;
	m_bClientFX				= DFALSE;

	m_pProjectileFilename	= "Sprites\\napalmprime.spr";
	m_pProjectileSkin		= 0;

	m_nDamageType			= DAMAGE_TYPE_EXPLODE;
	m_dwFlags				= m_dwFlags | FLAG_GRAVITY | FLAG_POINTCOLLIDE | FLAG_NOSLIDING;
	m_fStartTime			= g_pServerDE->GetTime();
	m_fLifeTime				= 10.0f;
	m_fDelay				= 0.01f;

	VEC_INIT(m_vInitScale);

	m_dwTrailFXID	= OBJFX_BUGSPRAY_1;
}


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

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

	DBOOL bRet = CProjectile::Update(pMovement);

	return bRet;
}


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

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

	DDWORD		nType = EXP_BUGSPRAY_PRIMARY;

	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\\Bugbuster\\impact.wav", 750.0f, SOUNDPRIORITY_MISC_MEDIUM);
}



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

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

CBugSprayAltProjectile::CBugSprayAltProjectile() : CProjectile(OT_SPRITE)
{
	m_bShockwave			= DFALSE;
	m_bExplosion			= DTRUE;
	m_bClientFX				= DFALSE;

	m_pProjectileFilename	= "Sprites\\napalmprime.spr";
	m_pProjectileSkin		= 0;

	m_nDamageType			= DAMAGE_TYPE_FIRE;
	m_fStartTime			= g_pServerDE->GetTime();
	m_dwFlags				= m_dwFlags | FLAG_GRAVITY | FLAG_POINTCOLLIDE | FLAG_NOSLIDING;
	m_fLifeTime				= 10.0f;
	m_fDelay				= 0.01f;

	VEC_INIT(m_vInitScale);

	m_dwTrailFXID	= OBJFX_BUGSPRAY_2;
}


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

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

	DBOOL bRet = CProjectile::Update(pMovement);

	return bRet;
}


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

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

	DDWORD		nType = EXP_BUGSPRAY_ALT;

	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\\Bugbuster\\altimpact.wav", 750.0f, SOUNDPRIORITY_MISC_MEDIUM);
}



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

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

CDeathRayProjectile::CDeathRayProjectile() : CProjectile(OT_NORMAL)
{
	m_bShockwave			= DFALSE;
	m_bExplosion			= DTRUE;
	m_bClientFX				= DFALSE;

	m_nDamageType			= DAMAGE_TYPE_ELECTRIC;
	m_dwFlags				= m_dwFlags | FLAG_POINTCOLLIDE;
	m_fLifeTime				= 0.0f;

	m_fStartTime			= 0.0f;
	m_fBounceDist			= 0.0f;
	m_bFirstUpdate			= DTRUE;
	m_bFirstShot			= DTRUE;

	VEC_INIT(m_vInitScale);
}


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

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

	pServerDE->SetNextUpdate(m_hObject, (DFLOAT)0.001);

	if(m_bFirstUpdate)
	{
		DRotation	rRot;
		DVector		vTemp;

		// Find a forward vector to fire with...
		pServerDE->GetObjectRotation(m_hObject, &rRot);
		pServerDE->GetRotationVectors(&rRot, &vTemp, &vTemp, &m_vBeamDir);

		m_bFirstUpdate = DFALSE;
	}

	// If it's time to reflect off of something... then cast a new ray
	if(pServerDE->GetTime() - m_fStartTime > DEATHRAY_BOUNCE_DELAY)
	{
		IntersectQuery	iq;
		IntersectInfo	ii;
		DVector			vDist;

		// Set the start and dest points for the intersection
		pServerDE->GetObjectPos(m_hObject, &(iq.m_From));
		VEC_MULSCALAR(vDist, m_vBeamDir, 3000.0f)
		VEC_ADD(iq.m_To, iq.m_From, vDist);

		iq.m_Flags = INTERSECT_OBJECTS | IGNORE_NONSOLID;
		iq.m_FilterFn = LiquidFilterFn;
		iq.m_pUserData = NULL;	

		DBOOL bHit;
		
		if(bHit = pServerDE->IntersectSegment(&iq, &ii))
		{
			if(m_bFirstShot && m_hFiredFrom == ii.m_hObject)
			{
				VEC_COPY(iq.m_From, ii.m_Point);
				bHit = pServerDE->IntersectSegment(&iq, &ii);		
			}
		}

		m_bFirstShot = DFALSE;

		// Test to see if we hit anything...
		if(bHit)
		{
			HCLASS	hObjClass   = pServerDE->GetObjectClass(ii.m_hObject);

			// Create the client side laser effect
			HMESSAGEWRITE hMessage = pServerDE->StartInstantSpecialEffectMessage(&(iq.m_From));
			pServerDE->WriteToMessageByte(hMessage, SFX_LASERBEAM_ID);

			pServerDE->WriteToMessageVector(hMessage, &(iq.m_From));
			pServerDE->WriteToMessageVector(hMessage, &(ii.m_Point));
			pServerDE->WriteToMessageByte(hMessage, LASER_GREEN_SMALL);

			pServerDE->EndMessage2(hMessage, MESSAGE_GUARANTEED);

			// Add a little effect and damage the object we hit
			AddExplosion(ii.m_Point, ii.m_Plane.m_Normal);
			DamageObject(m_hFiredFrom, this, ii.m_hObject, m_fDamage, vDist, ii.m_Point, m_nDamageType);

			// If we hit a destructable object, don't reflect...
			if(pServerDE->IsKindOf(hObjClass, pServerDE->GetClass("CBaseCharacter")))
				return DFALSE;

			// End the beam if we hit the sky (don't reflect)
			SurfaceType eType = GetSurfaceType(ii.m_hObject, ii.m_hPoly);
			if (eType == SURFTYPE_SKY)
				return DFALSE;

			// Add the distance to the bounce distance
			VEC_SUB(vDist, ii.m_Point, iq.m_From);
			m_fBounceDist += VEC_MAG(vDist);

			if(m_fBounceDist > DEATHRAY_BOUNCE_DIST)
				return DFALSE;

			// Otherwise, find a new direction to reflect
			pServerDE->TeleportObject(m_hObject, &ii.m_Point);

			DVector		vTemp;
			VEC_COPY(vTemp, ii.m_Plane.m_Normal);

			VEC_NORM(vDist);
			VEC_NORM(vTemp);

			// Calculate a reflection vector
			DFLOAT	dot = VEC_DOT(vTemp, vDist);
			VEC_MULSCALAR(m_vBeamDir, vTemp, 2.0f * -dot);
			VEC_ADD(m_vBeamDir, vDist, m_vBeamDir);
			VEC_NORM(m_vBeamDir);

			m_fStartTime = pServerDE->GetTime();
		}
		else
		{
			// We didn't hit anything... so create the beam from start to end
			// Create the client side laser effect
			HMESSAGEWRITE hMessage = pServerDE->StartInstantSpecialEffectMessage(&(iq.m_From));
			pServerDE->WriteToMessageByte(hMessage, SFX_LASERBEAM_ID);

			pServerDE->WriteToMessageVector(hMessage, &(iq.m_From));
			pServerDE->WriteToMessageVector(hMessage, &(iq.m_To));
			pServerDE->WriteToMessageByte(hMessage, LASER_GREEN_SMALL);

			pServerDE->EndMessage2(hMessage, MESSAGE_GUARANTEED);
			return DFALSE;
		}
	}

	return DTRUE;
}


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

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

	DDWORD		nType = EXP_DEATHRAY_PRIMARY;

	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\\laser\\impact.wav", 750.0f, SOUNDPRIORITY_MISC_MEDIUM);
}



BEGIN_CLASS(CLeechPrimeProjectile)
END_CLASS_DEFAU

⌨️ 快捷键说明

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