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

📄 corpse.cpp

📁 Blood 2全套源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// DESCRIPTION	: 
//
// RETURN TYPE	: int
//
// ----------------------------------------------------------------------- //

int CCorpse::CalculateHitLimb(DVector vDir, DVector vPos)
{
	int nNode = -1;
	DFLOAT fNodeDist = 0.0f, fDist = 999.0f, fTemp = 0.0f;
	DVector vShot, vNewShot, vTemp, vObjDims, vNodePos, vZ;
	DFLOAT fX, fY, ft;
	DBOOL bStatus = DFALSE;
	DRotation rRot;

	g_pServerDE->GetModelAnimUserDims(m_hObject, &vObjDims, g_pServerDE->GetModelAnimation(m_hObject));

	vTemp.x = (float)fabs(vDir.x);
	vTemp.y = (float)fabs(vDir.y);
	vTemp.z = (float)fabs(vDir.z);

	if(vTemp.x > vTemp.y && vTemp.x > vTemp.z)
	{
		fTemp = vObjDims.x / vTemp.x;
	}
	else if(vTemp.y > vTemp.x  && vTemp.y > vTemp.z)
	{
		fTemp = vObjDims.y / vTemp.y;
	}
	else if(vTemp.z > vTemp.x  && vTemp.z > vTemp.y)
	{
		fTemp = vObjDims.z / vTemp.z;
	}

	VEC_MULSCALAR(vNewShot,vDir,fTemp);
	VEC_ADD(vShot,vPos,vNewShot);

	DVector vC;
	VEC_SUB(vC,vShot,vPos);

	fX = 1 / VEC_DOT(vC,vC);
	fY = fX * -(VEC_DOT(vC,vPos));
	
	for(int i = 0; i < NUM_STD_NODES; i++)
	{
		g_pServerDE->GetModelNodeHideStatus(m_hObject, szNodes[i], &bStatus);

		if(!bStatus)
		{
			DBOOL bRet = g_pServerDE->GetModelNodeTransform(m_hObject, szNodes[i], &vNodePos, &rRot);

			ft = VEC_DOT(vC,vNodePos) * fX + fY;

			if(ft >= 0.0f && ft <= 1.0f)
			{
				VEC_ADDSCALED(vZ,vPos,vC, ft);

				fNodeDist = VEC_DIST(vNodePos, vZ);

				if(fNodeDist < fDist && fNodeDist <= m_fHitSpheres[i])
				{
					fDist = fNodeDist;
					nNode = i;
				}
			}
		}
	}

	//Do we leave a pass through mark behind us?
	if(nNode != -1)
	{
//		CWeapon weap(WEAP_BERETTA);

//		VEC_MULSCALAR(vTemp,vDir,-1.0f);
//		weap.AddSparks(vPos, vTemp, m_fHitPoints, m_hObject, SURFTYPE_FLESH);	
//		weap.AddBloodSpurt(vPos, vTemp, m_fHitPoints, m_hObject, SURFTYPE_FLESH);
		
//		vTemp.x *= -1.0f;
//		vTemp.z *= -1.0f;
//		weap.AddBloodSpurt(vPos, vTemp, m_fHitPoints, m_hObject, SURFTYPE_FLESH);	
	}

	return nNode;
}

// ----------------------------------------------------------------------- //
// ROUTINE		: CCorpse::SetProperNode
// DESCRIPTION	: Set the hit node to the parent node of the limb
// RETURN TYPE	: int 
// PARAMS		: int nNode
// ----------------------------------------------------------------------- //

int CCorpse::SetProperNode(int nNode)
{
	switch(nNode)
	{
		case 0:		return NODE_NECK;
		case 1:		return NODE_NECK;
		case 2:		return NODE_TORSO;
		case 3:		return NODE_TORSO;
		case 4:		return NODE_RARM;
		case 5:		return NODE_RARM;
		case 6:		return NODE_RARM;
		case 7:		return NODE_LARM;
		case 8:		return NODE_LARM;
		case 9:		return NODE_LARM;
		case 10:	return NODE_LLEG;
		case 11:	return NODE_LLEG;
		case 12:	return NODE_LLEG;
		case 13:	return NODE_LLEG;
		case 14:	return NODE_RLEG;
		case 15:	return NODE_RLEG;
		case 16:	return NODE_RLEG;
		case 17:	return NODE_RLEG;
		default:	return -1;
	}

	return -1;
}

void CCorpse::GenerateHitSpheres()
{
	DVector vNodePos[NUM_STD_NODES];
	DRotation rRot;

	for(int i = 0; i < NUM_STD_NODES; i++)
	{
		g_pServerDE->GetModelNodeTransform(m_hObject, szNodes[i], &vNodePos[i], &rRot);
	}

	//HEAD/NECK
	m_fHitSpheres[0] = VEC_DIST(vNodePos[0],vNodePos[1]) * 0.66f;
	m_fHitSpheres[1] = m_fHitSpheres[0];

	//TORSO/PELVIS
	m_fHitSpheres[2] = VEC_DIST(vNodePos[2],vNodePos[3]) * 0.66f;
	m_fHitSpheres[3] = m_fHitSpheres[2];

	//R_ARM
	m_fHitSpheres[4] = VEC_DIST(vNodePos[4],vNodePos[5]) * 0.66f;
	m_fHitSpheres[5] = VEC_DIST(vNodePos[5],vNodePos[6]) * 0.66f;
	m_fHitSpheres[6] = m_fHitSpheres[5];

	//L_ARM
	m_fHitSpheres[7] = VEC_DIST(vNodePos[7],vNodePos[8]) * 0.66f;
	m_fHitSpheres[8] = VEC_DIST(vNodePos[8],vNodePos[9]) * 0.66f;
	m_fHitSpheres[9] = m_fHitSpheres[8];

	//L_LEG
	m_fHitSpheres[10] = VEC_DIST(vNodePos[10],vNodePos[11]) * 0.66f;
	m_fHitSpheres[11] = VEC_DIST(vNodePos[11],vNodePos[12]) * 0.66f;
	m_fHitSpheres[12] = VEC_DIST(vNodePos[12],vNodePos[13]) * 0.66f;
	m_fHitSpheres[13] = m_fHitSpheres[12];

	//R_LEG
	m_fHitSpheres[14] = VEC_DIST(vNodePos[14],vNodePos[15]) * 0.66f;
	m_fHitSpheres[15] = VEC_DIST(vNodePos[15],vNodePos[16]) * 0.66f;
	m_fHitSpheres[16] = VEC_DIST(vNodePos[16],vNodePos[17]) * 0.66f;
	m_fHitSpheres[17] = m_fHitSpheres[16];

	return;
}


// ----------------------------------------------------------------------- //
// ROUTINE		: CCorpse::CreateGibs
// DESCRIPTION	: create some nastiness
// RETURN TYPE	: void 
// ----------------------------------------------------------------------- //

DBOOL CCorpse::CreateGibs(DVector vDir, int nNumGibs, int nType, DFLOAT fDamage)
{
//	HCLASS hClass = g_pServerDE->GetClass( "CClientGibFX" );
//	if( !hClass )
//		return DFALSE;


	DFLOAT fVel = 50.0f + fDamage;

	vDir.y -= 1.0f;
	VEC_NORM(vDir);

	VEC_MULSCALAR(vDir, vDir, fVel);

//	ObjectCreateStruct ocStruct;
//	INIT_OBJECTCREATESTRUCT(ocStruct);

	DVector vPos;
	g_pServerDE->GetObjectPos(m_hObject, &vPos);
//	VEC_COPY(ocStruct.m_Pos, vPos);
//	g_pServerDE->GetObjectRotation(m_hObject, &ocStruct.m_Rotation);

//	CClientGibFX* pGib = (CClientGibFX*)g_pServerDE->CreateObject(hClass, &ocStruct);

	DVector vDims;
	g_pServerDE->GetObjectDims(m_hObject, &vDims);

/*	if(nType & DAMAGE_TYPE_EXPLODE)
		pGib->Setup(&vPos, &vDir, &vDims, (SURFTYPE_FLESH/10) | SIZE_SMALL | TRAIL_BLOOD, 1.0f, nNumGibs);
	else
		pGib->Setup(&vPos, &vDir, &vDims, (SURFTYPE_FLESH/10) | SIZE_SMALL | TRAIL_BLOOD, 1.0f, nNumGibs); 
*/
	SetupClientGibFX(&vPos, &vDir, &vDims, (SURFTYPE_FLESH/10) | SIZE_SMALL | TRAIL_BLOOD, 1.0f, nNumGibs);

	// Create body parts

	if(m_bLimbLoss)
	{
		// 100 % create a head..
		DBOOL bNodeStatus;
		if (g_pServerDE->GetModelNodeHideStatus(m_hObject, szNodes[NODE_NECK], &bNodeStatus) == DE_OK)
		{
			if (!bNodeStatus)	// not hidden
				AIShared.CreateLimb(m_hObject, NODE_NECK, vDir);
		}

		if (g_pServerDE->GetModelNodeHideStatus(m_hObject, szNodes[NODE_RARM], &bNodeStatus) == DE_OK)
		{
			if (!bNodeStatus && IsRandomChance(80))
				AIShared.CreateLimb(m_hObject, NODE_RARM, vDir);
		}

		if (g_pServerDE->GetModelNodeHideStatus(m_hObject, szNodes[NODE_LARM], &bNodeStatus) == DE_OK)
		{
			if (!bNodeStatus && IsRandomChance(80))
				AIShared.CreateLimb(m_hObject, NODE_LARM, vDir);
		}

		if (g_pServerDE->GetModelNodeHideStatus(m_hObject, szNodes[NODE_RLEG], &bNodeStatus) == DE_OK)
		{
			if (!bNodeStatus && IsRandomChance(60))
				AIShared.CreateLimb(m_hObject, NODE_RLEG, vDir);
		}

		if (g_pServerDE->GetModelNodeHideStatus(m_hObject, szNodes[NODE_LLEG], &bNodeStatus) == DE_OK)
		{
			if (!bNodeStatus && IsRandomChance(60))
				AIShared.CreateLimb(m_hObject, NODE_LLEG, vDir);
		}
	}

	return DTRUE;
}


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

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

	for (int i=0; i < NUM_STD_NODES; i++)
		pServerDE->WriteToMessageFloat(hWrite, m_fHitSpheres[i]);

	pServerDE->WriteToMessageFloat(hWrite, m_fMass);
	pServerDE->WriteToMessageFloat(hWrite, m_fHitPoints);

	pServerDE->WriteToMessageString(hWrite, m_szSoundDir);
	pServerDE->WriteToMessageByte(hWrite, m_bLimbLoss);
}


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

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

	for (int i=0; i < NUM_STD_NODES; i++)
		m_fHitSpheres[i] = pServerDE->ReadFromMessageFloat(hRead);

	m_fMass			= pServerDE->ReadFromMessageFloat(hRead);
	m_fHitPoints	= pServerDE->ReadFromMessageFloat(hRead);

	_mbscpy((unsigned char*)m_szSoundDir, (const unsigned char*)pServerDE->ReadFromMessageString(hRead));

	m_bLimbLoss		= pServerDE->ReadFromMessageByte(hRead);
}

// ----------------------------------------------------------------------- //
// ROUTINE		: CCorpse::OnStringKey
// DESCRIPTION	: read and parse string keys
// RETURN TYPE	: void 
// PARAMS		: ArgList* pArgList
// ----------------------------------------------------------------------- //

void CCorpse::OnStringKey(ArgList* pArgList)
{
	if (!g_pServerDE || !pArgList || !pArgList->argv || pArgList->argc == 0) return;

	char* pKey = pArgList->argv[0];
	if (!pKey) return;

	char szTemp[32];
	szTemp[0] = '\0';

	if (m_szSoundDir[0] != '\0' && Sparam_Get(szTemp,pKey,"play_sound"))
	{
		char szSound[256];
		char szTmp[32];

		szSound[0] = '\0';
		szTmp[0]   = '\0';

		if(Sparam_Get(szTmp,pKey,"sound_random"))
		{
			int nMax = atoi(szTmp);
			int nNum = g_pServerDE->IntRandom(1,NRES(nMax));
			sprintf(szSound, "%s\\%s%d.wav", m_szSoundDir, szTemp, nNum);
		}
		else
		{
			sprintf(szSound, "%s\\%s.wav", m_szSoundDir, szTemp);
		}

		DFLOAT fRadius = 1000.0f;

		if(Sparam_Get(szTmp,pKey,"sound_radius"))
		{
			fRadius = (DFLOAT)atof(szTmp);
		}

		int nVol = 100;

		if(Sparam_Get(szTmp,pKey,"sound_volume"))
		{
			nVol = atoi(szTmp);
		}

		PlayAISound(szSound, fRadius, 0, nVol);
	}

	return;
}

// ----------------------------------------------------------------------- //
// ROUTINE		: CCorpse::PlayAISound
// DESCRIPTION	: 
// RETURN TYPE	: DBOOL 
// PARAMS		: char* szSound
// PARAMS		: DFLOAT fRadius
// ----------------------------------------------------------------------- //

DBOOL CCorpse::PlayAISound(char* szSound, DFLOAT fRadius, DDWORD dwFlags, int nVol)
{
	if (m_hCurSound)
	{
		DBOOL bIsSoundDone;

		if( !( dwFlags & PLAY_INTERRUPT))
			return DFALSE;
		if(  ((dwFlags & PLAY_WAIT) && g_pServerDE->IsSoundDone(m_hCurSound, &bIsSoundDone) == LT_OK && !bIsSoundDone))
			return DFALSE;

		g_pServerDE->KillSound( m_hCurSound );
		m_hCurSound = DNULL;
	}

	PlaySoundInfo playSoundInfo;
	PLAYSOUNDINFO_INIT( playSoundInfo );

	playSoundInfo.m_dwFlags = PLAYSOUND_3D | PLAYSOUND_ATTACHED | PLAYSOUND_REVERB;

//	playSoundInfo.m_dwFlags |= PLAYSOUND_LOOP;
//	playSoundInfo.m_dwFlags |=  PLAYSOUND_GETHANDLE;
//	playSoundInfo.m_dwFlags |= PLAYSOUND_FILESTREAM;
//	playSoundInfo.m_dwFlags |=  PLAYSOUND_TIME;

	if(nVol < 100)
		playSoundInfo.m_dwFlags |= PLAYSOUND_CTRL_VOL;
	
	_mbsncpy((unsigned char*)playSoundInfo.m_szSoundName, (const unsigned char*)szSound, _MAX_PATH );
	playSoundInfo.m_hObject = m_hObject;
	playSoundInfo.m_nPriority = SOUNDPRIORITY_AI_MEDIUM;
	playSoundInfo.m_fOuterRadius = fRadius;
	playSoundInfo.m_fInnerRadius = fRadius * 0.1f;
	playSoundInfo.m_nVolume = nVol;
	
	g_pServerDE->PlaySound( &playSoundInfo );

	m_hCurSound = playSoundInfo.m_hSound;

	return DTRUE;
}


// ----------------------------------------------------------------------- //
// ROUTINE		: CCorpse::CreateBloodPool
// DESCRIPTION	: 
// RETURN TYPE	: void
// PARAMS		: none
// ----------------------------------------------------------------------- //

void CCorpse::CreateBloodPool()
{
	ObjectCreateStruct ocStruct;
	INIT_OBJECTCREATESTRUCT(ocStruct);

	IntersectQuery iq;
	IntersectInfo  ii;

	g_pServerDE->GetObjectPos(m_hObject, &iq.m_From);
	VEC_COPY(iq.m_To, iq.m_From);
	iq.m_To.y -= 40.0f;

	iq.m_Flags = IGNORE_NONSOLID;
	iq.m_FilterFn = NULL;
	iq.m_pUserData = NULL;	

	if (g_pServerDE->IntersectSegment(&iq, &ii))
	{
		// Only care if we hit the world
		if (ii.m_hObject == g_pServerDE->GetWorldObject())
		{
			HCLASS hClass = g_pServerDE->GetClass("CClientSplatFX");
			ii.m_Point.y += 0.1f;

			CClientSplatFX *pSplat = DNULL;
			if (hClass)
			{
				VEC_COPY(ocStruct.m_Pos, ii.m_Point);
				pSplat = (CClientSplatFX *)g_pServerDE->CreateObject(hClass, &ocStruct);
			}

			if (pSplat)
			{
				pSplat->Setup( &ii.m_Point, &ii.m_Plane.m_Normal, 0.10f, 0.02f);
			}
		}
	}
}

⌨️ 快捷键说明

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