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

📄 gameweapons.cpp

📁 Blood 2全套源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CHandSqueeze::Fire()
//
//	PURPOSE:	Fires the weapon
//
// ----------------------------------------------------------------------- //
DDWORD CHandSqueeze::Fire()
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE)
		return 0;

	DBOOL bAltFire = (m_eState == WS_ALT_FIRING);

	int sound = pServerDE->IntRandom(0, 4);

	if (sound < 1)		m_szFireSound = "Sounds\\Slash1.wav";
	else if (sound < 2) m_szFireSound = "Sounds\\Slash2.wav";
	else if (sound < 3)	m_szFireSound = "Sounds\\Slash3.wav";
	else				m_szFireSound = "Sounds\\Slash4.wav";

	return CWeapon::Fire();
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CFlareGun::FireSpread()
//
//	PURPOSE:	Spread the flare shots
//
// ----------------------------------------------------------------------- //

void CFlareGun::FireSpread(Spread *spread, DDWORD shots, DFLOAT range, DBOOL bAltFire, DVector *rDir)
{
	//***** Make sure the server and inventory systems are valid *****//
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !m_pInventoryMgr)		return;

	//***** Variables to calculate the spread of the weapon fire *****//
	DFLOAT		hOffset, vOffset;
	DVector		vTmp, vFire;
	DVector		vU, vR, vF;
	DBOOL		bTracer = DFALSE;
	pServerDE->GetRotationVectors(&m_rRotation, &vU, &vR, &vF); 

	// Check to see if the player is standing too close to something, and we need
	// to move the firing position back in order to hit it
	if(IsPlayer(m_hOwner) && FiringTooClose(&vF, 60.0f, &vTmp))
		{ VEC_COPY(m_vPosition, vTmp); }

	for(int i = (shots - 1); i >= 0; i--)
	{
		VEC_COPY(vFire, vF)
        
		if(shots - 1)
			switch(i)
			{
				case	7:	hOffset = 0.03f; vOffset = 0.03f;	break;
				case	6:	hOffset = -0.03f; vOffset = -0.03f;	break;
				case	5:	hOffset = -0.03f; vOffset = 0.03f;	break;
				case	4:	hOffset = 0.03f; vOffset = -0.03f;	break;
				case	3:	hOffset = 0.0f; vOffset = 0.08f;	break;
				case	2:	hOffset = 0.0f; vOffset = -0.08f;	break;
				case	1:	hOffset = -0.08f; vOffset = 0.0f;	break;
				case	0:	hOffset = 0.08f; vOffset = 0.0f;	break;
				default:	hOffset = 0.0f; vOffset = 0.0f;		break;
			}
		else
		{
			hOffset = pServerDE->Random(-spread->h, spread->h) / 2000;
			vOffset = pServerDE->Random(-spread->v, spread->v) / 2000;
		}

		VEC_MULSCALAR(vTmp, vR, hOffset)
		VEC_ADD(vFire, vFire, vTmp)

		VEC_MULSCALAR(vTmp, vU, vOffset)
		VEC_ADD(vFire, vFire, vTmp)

		VEC_NORM(vFire)

		if(m_bAccuracyCheck && IsPlayer(m_hOwner))
			AlignFireVector(&vFire, range);

		FireProjectile(&vFire, range, (m_eState == WS_ALT_FIRING));
	}

	VEC_COPY(*rDir, vR);
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CVoodooDoll::FireVector()
//
//	PURPOSE:	Fires a vector
//
// ----------------------------------------------------------------------- //

DBOOL CVoodooDoll::FireVector(DVector *vFire, DFLOAT dist, DBOOL bTracer)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if(!pServerDE)	return DFALSE;

	switch(m_nHitFX)
	{
		case	0:		m_nHitType = DAMAGE_TYPE_NORMAL;		break;
		case	1:		m_nHitType = DAMAGE_TYPE_NORMAL;		break;
		case	2:		m_nHitType = DAMAGE_TYPE_BLIND;			break;
		case	3:		m_nHitType = DAMAGE_TYPE_DROPWEAPON;	break;
		case	4:		m_nHitType = DAMAGE_TYPE_SLOW;			break;
		default:		m_nHitType = DAMAGE_TYPE_NORMAL;		break;
	}

	if(m_eState == WS_FIRING)
	{
		DamageClosestInFOV();
	}
	else if(m_eState == WS_ALT_FIRING)
	{
		m_nHitFX = 5;
		m_nHitType = DAMAGE_TYPE_VISION;	// Wonkie vision (violet)

		m_fDamage = pServerDE->Random(m_fMinAltDamage, m_fMaxAltDamage);

		if (!WonkyThemAll(WONKY_VISION_DEFAULT_TIME))
		{
			// If you miss everyone with the alt fire, you just explode cause you suck
			BaseClass *ffObj = pServerDE->HandleToObject(m_hOwner);
			DVector		vFire, vPos;

			VEC_SET(vFire, 0.0f, -1.0f, 0.0f);
			pServerDE->GetObjectPos(m_hOwner, &vPos);

			HMESSAGEWRITE hMsg = pServerDE->StartMessageToObject(ffObj, m_hOwner, MID_DAMAGE);
			pServerDE->WriteToMessageVector(hMsg, &vFire);
			pServerDE->WriteToMessageFloat(hMsg, 100.0f);
			pServerDE->WriteToMessageByte(hMsg, DAMAGE_TYPE_EXPLODE);
			pServerDE->WriteToMessageObject(hMsg, m_hOwner);
			pServerDE->WriteToMessageVector(hMsg, &vPos);
			pServerDE->EndMessage2(hMsg, MESSAGE_GUARANTEED | MESSAGE_NAGGLEFAST);
		}
	}

	return DTRUE;
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CVoodooDoll::SendDamageMsg()
//
//	PURPOSE:    VoodooDoll Damage Message
//
// ----------------------------------------------------------------------- //

DBOOL CVoodooDoll::SendDamageMsg(HOBJECT firedTo, DVector vPoint, int nNode, DVector *vFire, DFLOAT m_nDamage)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();

	if (!pServerDE)
		return DFALSE;

	BaseClass *ffObj = pServerDE->HandleToObject(m_hOwner);

	// Send a damage message to the object
	HMESSAGEWRITE hMsg = pServerDE->StartMessageToObject(ffObj, firedTo, MID_DAMAGE);
	pServerDE->WriteToMessageVector(hMsg, vFire);
    pServerDE->WriteToMessageFloat(hMsg, (float)m_nDamage * GetDamageMultiplier());
    pServerDE->WriteToMessageByte(hMsg, (char)m_nHitType);
	pServerDE->WriteToMessageObject(hMsg, m_hOwner);
	pServerDE->WriteToMessageVector(hMsg, &vPoint);
	pServerDE->EndMessage2(hMsg, MESSAGE_GUARANTEED | MESSAGE_NAGGLEFAST);

	return DTRUE;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CVoodooDoll::DamageClosestInFOV()
//
//	PURPOSE:    Search for the closest person to damage
//
// ----------------------------------------------------------------------- //

DBOOL CVoodooDoll::DamageClosestInFOV()
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE)	return DNULL;

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

	// Work with the squares of the distances so as to not have to get a square root.
	HOBJECT		hObj;
	HOBJECT		hDamageObj = DNULL;
	DFLOAT		fLastDist = 3000.0f;
	DVector		vPoint, vDirection;

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

	DBOOL		bHitSomething = DFALSE;

	// Get a forward vector and position of the player who shot the voodoo doll
   	CPlayerObj	*pObj = (CPlayerObj*)pServerDE->HandleToObject(m_hOwner);
	DVector		vOwnerF, vOwnerPos;
	pObj->GetPlayerForward(&vOwnerF);
	pServerDE->GetObjectPos(m_hOwner, &vOwnerPos);
	VEC_NORM(vOwnerF);

	CPlayerObj* pOwnerPlayer = pObj;

	// 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, fAngle;

			// If it's us... skip to the next in the list
			if(hObj == m_hOwner)
				{ pLink = pLink->m_pNext; continue; }

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

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

			VEC_NORM(vDir);
			fAngle = VEC_DOT(vDir, vOwnerF);

			// If the target isn't within our square FOV, then skip it
			if(fAngle < VOODOO_PRIMARY_FOV)
				{ pLink = pLink->m_pNext; continue; }

			// Make sure there's nothing blocking our view of the character
			IntersectQuery iq;
			IntersectInfo  ii;
    
			VEC_COPY(iq.m_From, vOwnerPos);
			VEC_COPY(iq.m_To, vObjPos);
			VEC_MULSCALAR(vDir, vDir, 15.0f);
			VEC_ADD(iq.m_To, iq.m_To, vDir);
    
			iq.m_Flags = INTERSECT_OBJECTS | IGNORE_NONSOLID;
			iq.m_FilterFn = LiquidFilterFn;
			iq.m_pUserData = NULL;	

			if(pServerDE->IntersectSegment(&iq, &ii))
			{
				if(ii.m_hObject == hObj)
				{
					if(fDist < fLastDist)
					{
						fLastDist = fDist;
						hDamageObj = hObj;
						bHitSomething = DTRUE;
						VEC_COPY(vPoint, ii.m_Point);
						VEC_COPY(vDirection, vDir);
					}
				}
			}
		}

		pLink = pLink->m_pNext;
	}

	// Handle the object damage and effect

	if(hDamageObj)
	{
		hObjClass = pServerDE->GetObjectClass(hDamageObj);

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

			if (!pOwnerPlayer->IsPlayerDamageOk(pObj))	// [blg] check for team-play and friendly-fire
			{
				return(DTRUE);
			}

			if(m_nHitFX == 2)
			{
				HMESSAGEWRITE hMsg = pServerDE->StartMessage(pObj->GetClient(), SMSG_BLIND);
				pServerDE->WriteToMessageFloat(hMsg, 5.0f);
				pServerDE->EndMessage2(hMsg, MESSAGE_GUARANTEED | MESSAGE_NAGGLEFAST);
			}
			if(m_nHitFX == 3)
			{
				// Make the character holster his weapon
			}
			if(m_nHitFX == 4)
			{
				pObj->Slow(5.0f);
			}
		}

		//******************************************************************
		if(m_nHitFX == 1)
			SendDamageMsg(hDamageObj, vPoint, 999, &vDirection, m_fDamage * 2.0f);
		else
			SendDamageMsg(hDamageObj, vPoint, 999, &vDirection, m_fDamage);

		//******************************************************************
		// Create a particle effect around the hit character
		DVector		offset;
		DDWORD		fxType = OBJFX_VOODOO_1 + m_nHitFX;
		VEC_SET(offset, 0.0f, 0.0f, 0.0f);

		HMESSAGEWRITE hMessage = pServerDE->StartInstantSpecialEffectMessage(&offset);
		pServerDE->WriteToMessageByte(hMessage, SFX_OBJECTFX_ID);

		pServerDE->WriteToMessageObject(hMessage, hDamageObj);
		pServerDE->WriteToMessageVector(hMessage, &offset);
		pServerDE->WriteToMessageFloat(hMessage, 0.0f);
		pServerDE->WriteToMessageDWord(hMessage, 0);
		pServerDE->WriteToMessageDWord(hMessage, fxType);
		pServerDE->WriteToMessageDWord(hMessage, 0);

		pServerDE->EndMessage2(hMessage, MESSAGE_GUARANTEED | MESSAGE_NAGGLEFAST);
		//******************************************************************

		if(m_nHitFX == 4)
			pServerDE->SetVelocity(hDamageObj, &offset);
	}
	else
	{
		SendDamageMsg(m_hOwner, vOwnerPos, 999, &vDirection, m_fDamage / 3.0f);
	}

	return bHitSomething;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CVoodooDoll::WonkyThemAll()
//
//	PURPOSE:    Search for people to wonky
//
// ----------------------------------------------------------------------- //

DBOOL CVoodooDoll::WonkyThemAll(DFLOAT fWonkyTime)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE)	return DNULL;

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

	// Work with the squares of the distances so as to not have to get a square root.
	HOBJECT		hObj;

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

	DBOOL		bHitSomething = DFALSE;

	// Get a forward vector and position of the player who shot the voodoo doll
   	CPlayerObj	*pObj = (CPlayerObj*)pServerDE->HandleToObject(m_hOwner);
	DVector		vOwnerF, vOwnerPos;
	pObj->GetPlayerForward(&vOwnerF);
	pServerDE->GetObjectPos(m_hOwner, &vOwnerPos);
	VEC_NORM(vOwnerF);

	CPlayerObj* pOwnerPlayer = pObj;

	// 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, fAngle;

			// If it's us... skip to the next in the list
			if(hObj == m_hOwner)
				{ pLink = pLink->m_pNext; continue; }

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

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

			VEC_NORM(vDir);
			fAngle = VEC_DOT(vDir, vOwnerF);

			// If the target isn't within our square FOV, then skip it
			if(fAngle < VOODOO_WONKY_FOV)
				{ pLink = pLink->m_pNext; continue; }

			// If it's a team-mate and there's no friendly-fire, then skip it
			if (!pOwnerPlayer->IsPlayerDamageOk(hObj))
			{
				pLink = pLink->m_pNext;
				bHitSomething = DTRUE;
				continue;
			}

			// Make sure there's nothing blocking our view of the character
			IntersectQuery iq;
			IntersectInfo  ii;
    
			VEC_COPY(iq.m_From, vOwnerPos);
			VEC_COPY(iq.m_To, vObjPos);
			VEC_MULSCALAR(vDir, vDir, 15.0f);
			VEC_ADD(iq.m_To, iq.m_To, vDir);
    
			iq.m_Flags = INTERSECT_OBJECTS | IGNORE_NONSOLID;
			iq.m_FilterFn = LiquidFilterFn;
			iq.m_pUserData = NULL;	

			if(pServerDE->IntersectSegment(&iq, &ii))
			{
				if(ii.m_hObject == hObj)
				{
					bHitSomething = DTRUE;
					VEC_NORM(vDir);

					SendDamageMsg(ii.m_hObject, ii.m_Point, 999, &vDir, m_fDamage);

					//******************************************************************
					// Create a particle effect around the hit character
					DVector		offset;
					VEC_SET(offset, 0.0f, 0.0f, 0.0f);

					HMESSAGEWRITE hMessage = pServerDE->StartInstantSpecialEffectMessage(&offset);
					pServerDE->WriteToMessageByte(hMessage, SFX_OBJECTFX_ID);

⌨️ 快捷键说明

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