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

📄 objectutilities.cpp

📁 Blood 2全套源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	if(pLink == DNULL)
		return;

	while(pLink != &AI_Mgr::m_CabalHead)
	{
		hObject = pServerDE->ObjectToHandle((BaseClass*)pLink->m_pData);

		if (!hObject)
			break;

		if(hObject != hSender)
		{
			pServerDE->GetObjectPos(hObject,&vAIPos);

			if(VEC_DISTSQR(vPos,vAIPos) <= fRadius)
			{
				sprintf(szTemp, "%s %d %.1f %.1f %.1f;", TRIGGER_SOUND, nId, vPos.x, vPos.y, vPos.z);

				LPBASECLASS lpClass = pServerDE->HandleToObject( hSender );
				HMESSAGEWRITE hMessage = pServerDE->StartMessageToObject( lpClass, hObject, MID_TRIGGER );
				HSTRING hString = pServerDE->CreateString( szTemp );
				pServerDE->WriteToMessageHString( hMessage, hString );
				pServerDE->FreeString( hString );
				pServerDE->EndMessage( hMessage );
			}
		}

		pLink = pLink->m_pNext;
	}

	pLink = AI_Mgr::m_MonsterHead.m_pNext;

	if(pLink == DNULL)
		return;

	while(pLink != &AI_Mgr::m_MonsterHead)
	{
		hObject = pServerDE->ObjectToHandle((BaseClass*)pLink->m_pData);

		if (!hObject)
			break;

		if(hObject != hSender)
		{
			pServerDE->GetObjectPos(hObject,&vAIPos);

			if(VEC_DISTSQR(vPos,vAIPos) <= fRadius)
			{
				sprintf(szTemp, "%s %d %.1f %.1f %.1f;", TRIGGER_SOUND, nId, vPos.x, vPos.y, vPos.z);

				LPBASECLASS lpClass = pServerDE->HandleToObject(hSender);
				HMESSAGEWRITE hMessage = pServerDE->StartMessageToObject(lpClass, hObject, MID_TRIGGER);
				HSTRING hString = pServerDE->CreateString(szTemp);
				pServerDE->WriteToMessageHString(hMessage, hString );
				pServerDE->FreeString( hString );
				pServerDE->EndMessage(hMessage);				
			}
		}

		pLink = pLink->m_pNext;
	}

	return;
}


//-------------------------------------------------------------------------------------------
//
// ROUTINE:		MoveObjectToGround
//
// PURPOSE:		Move this object down so that it rests on the object or world below it.
//
//-------------------------------------------------------------------------------------------

DBOOL MoveObjectToGround(HOBJECT hObject)
{
	if (!hObject || !g_pServerDE) return DFALSE;

	// Cast a ray to see what's below us
	IntersectQuery iq;
	IntersectInfo ii;

	DVector vPos;
	g_pServerDE->GetObjectPos(hObject, &vPos);

	VEC_COPY(iq.m_From, vPos);
	VEC_SET(iq.m_Direction, 0.0f, -1.0f, 0.0f);
	iq.m_Flags	   = IGNORE_NONSOLID | INTERSECT_OBJECTS;
	iq.m_FilterFn  = NULL;
	iq.m_pUserData = NULL;	

	if (g_pServerDE->CastRay(&iq, &ii))	// Hit
	{
		DVector vDims;

		if(g_pServerDE->IsKindOf(g_pServerDE->GetObjectClass(hObject), g_pServerDE->GetClass("CBaseCharacter")))
		{
			if(g_pServerDE->GetModelAnimUserDims(hObject, &vDims, 0) == DE_INVALIDPARAMS)
				g_pServerDE->DebugOut("MoveObjectToGround() fucked up\r\n");
		}
		else
			g_pServerDE->GetObjectDims(hObject, &vDims);

		DFLOAT fDist = vPos.y - ii.m_Point.y + 0.1f;
		if (fDist > vDims.y)
		{
			vPos.y = vPos.y - fDist + (vDims.y + 0.1f);
			g_pServerDE->MoveObject(hObject, &vPos);
			return DTRUE;
		}
	}

	return DFALSE;
}

DBOOL GlobalFilterFn(HOBJECT hObj, void *pUserData)
{
	DDWORD dwObject;
	GlobalFilterFnData *pGlobalFilterFnData;
	if (!hObj || !g_pServerDE) return DFALSE;

	if( !pUserData )
		return DTRUE;

	pGlobalFilterFnData = ( GlobalFilterFnData * )pUserData;

	if( pGlobalFilterFnData->m_nIgnoreObjects && pGlobalFilterFnData->m_hIgnoreObjects )
	{
		for( dwObject = 0; dwObject < pGlobalFilterFnData->m_nIgnoreObjects; dwObject++ )
		{
			if( pGlobalFilterFnData->m_hIgnoreObjects[dwObject] == hObj )
				return DFALSE;
		}
	}

	HCLASS hObjClass	= g_pServerDE->GetObjectClass(hObj);
	BaseClass* pObj = (BaseClass*)g_pServerDE->HandleToObject(hObj);			

	if( pGlobalFilterFnData->m_dwFlags & IGNORE_CHARACTER)
	{
		HCLASS hCharacter = g_pServerDE->GetClass("CBaseCharacter");

		if(g_pServerDE->IsKindOf(hObjClass, hCharacter))
			return DFALSE;
	}

	if( pGlobalFilterFnData->m_dwFlags & IGNORE_LIQUID)
	{
		HCLASS hLiquid	= g_pServerDE->GetClass("VolumeBrush");

		if(g_pServerDE->IsKindOf(hObjClass, hLiquid))
			return DFALSE;
	}

	if( pGlobalFilterFnData->m_dwFlags & IGNORE_DESTRUCTABLE)
	{
		HCLASS hDestruct = g_pServerDE->GetClass("CDestructableModel");

		if(g_pServerDE->IsKindOf(hObjClass, hDestruct))
		{
			CDestructableModel* pModel = (CDestructableModel*)g_pServerDE->HandleToObject(hObj);			

			if(pModel->IsDestructable())
				return DFALSE;
		}
	}

	if( pGlobalFilterFnData->m_dwFlags & IGNORE_GLASS)
	{
		HCLASS hBrush = g_pServerDE->GetClass("CDestructableBrush");

		if(g_pServerDE->IsKindOf(hObjClass, hBrush))
		{
			CDestructableBrush* pBrush = (CDestructableBrush*)g_pServerDE->HandleToObject(hObj);			

			if(pBrush->GetSurfaceType() == SURFTYPE_GLASS && pBrush->IsDestructable())
				return DFALSE;
		}
	}

	return DTRUE;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	DamageObject()
//
//	PURPOSE:	Damage the specified object
//
//  PARAMETERS:
//
//		hResponsible -	Handle to the object responsible for the damage 
//						(may or may not be the same as pDamager->m_hObject)
//		pDamager	 -	Pointer to the object that is doing the damage.
//		hDamagee	 -	Handle to the object taking the damage
//		fDamage		 -	The amount of damage being inflicted
//		vDir		 -	The direction the damage is coming from
//		nDamageType	 -	The type of damage being inflicted.
//
// ----------------------------------------------------------------------- //
void DamageObject(HOBJECT hResponsible, LPBASECLASS pDamager, 
						 HOBJECT hDamagee, DFLOAT fDamage, DVector vDir, DVector vPos,DBYTE nDamageType)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !pDamager || !hDamagee) return;

	// Damage object...

	HMESSAGEWRITE hMessage = pServerDE->StartMessageToObject(pDamager, hDamagee, MID_DAMAGE);
	pServerDE->WriteToMessageVector(hMessage, &vDir);
	pServerDE->WriteToMessageFloat(hMessage, fDamage);
	pServerDE->WriteToMessageByte(hMessage, nDamageType);
	pServerDE->WriteToMessageObject(hMessage, hResponsible);
	pServerDE->WriteToMessageVector(hMessage, &vPos);
	pServerDE->EndMessage(hMessage);
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	DamageObjectsInRadius()
//
//	PURPOSE:	Damage objects within a certain radius
//
//  PARAMETERS:
//
//		hResponsible -	Handle to the object responsible for the damage 
//						(may or may not be the same as pDamager->m_hObject)
//		pDamager	 -	Pointer to the object that is doing the damage.
//		vOrigin		 -	Center of the damage sphere
//		fRadius 	 -	The radius of the damage sphere
//		fDamage		 -	The amount of damage inflicted.
//		eType		 -	The type of damage being inflicted.
//
// ----------------------------------------------------------------------- //

void DamageObjectsInRadius(HOBJECT hResponsible, LPBASECLASS pDamager,
								  DVector vOrigin, DFLOAT fRadius,
								  DFLOAT fDamage, DBYTE nDamageType)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || fRadius <= 0.0f) return;

	// Set area of effect damage type flag, for those who care
	nDamageType |= DAMAGE_FLAG_AREAEFFECT;

	DLink* pLink = CDestructable::m_DestructableHead.m_pNext;
	if(!pLink)
		return;

	// small optimization..
	// Work with the squares of the distances so as to not have to get a square root.
	DFLOAT fRadiusSquared = fRadius * fRadius;
	DFLOAT fHalfRadiusSquared = fRadiusSquared/2;

	HOBJECT hObj;

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

		if (!hObj)
		{
			pLink = pLink->m_pNext;
			continue;
		}

		DVector vDir, vObjPos, vObjDims;
		pServerDE->GetObjectPos(hObj, &vObjPos);

		// Get the average of the objects dims
		pServerDE->GetObjectDims(hObj, &vObjDims);
		DFLOAT fAvgDim = (vObjDims.x + vObjDims.y + vObjDims.z) / 3.0f;
		fAvgDim = fAvgDim * fAvgDim;	
		
		VEC_SUB(vDir, vObjPos, vOrigin);
		DFLOAT fDistanceSquared = VEC_MAGSQR(vDir) - fAvgDim;

		// Apply full damage to 50% point, then reduce it
		if (fDistanceSquared < fHalfRadiusSquared) 
		{
			DamageObject(hResponsible, pDamager, hObj, fDamage, vDir, vOrigin, nDamageType);
		}
		else if (fDistanceSquared <= fRadiusSquared) 
		{
			DFLOAT fAdjDamage = fDamage - (fDistanceSquared - fHalfRadiusSquared) / fHalfRadiusSquared * fDamage;
			DamageObject(hResponsible, pDamager, hObj, fAdjDamage, vDir, vOrigin, nDamageType);
		}

		pLink = pLink->m_pNext;
	}
}


⌨️ 快捷键说明

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