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

📄 gib.cpp

📁 Blood 2全套源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Gib.cpp: implementation of the CGib class.
//
//////////////////////////////////////////////////////////////////////

#define GIB_REMOVETIME	20.0f


#include <stdio.h>
#include "Gib.h"
#include "ClientSmokeTrail.h"
#include "ObjectUtilities.h"
#include "clientbloodtrail.h"
#include "clientmarksfx.h"
#include "BloodServerShell.h"
#include "ClientWeaponSFX.h"
#include "SfxMsgIDs.h"
#include <mbstring.h>
#include "SoundTypes.h"

//FLESH
char *szFleshGibs[NUM_FLESH_GIBS] = 
{
	"models\\gibs\\giblarge2.abc",
	"models\\gibs\\giblarge2.abc",
	"models\\gibs\\giblarge3.abc"
};

char *szFleshSkins[NUM_FLESH_GIBS] = 
{
	"skins\\gibs\\giblarge2.dtx",
	"skins\\gibs\\giblarge2.dtx",
	"skins\\gibs\\giblarge3.dtx"
};

//METAL
char *szMetalGibs[NUM_METAL_GIBS] = 
{
	"models\\gibs\\gibmetal1.abc",
	"models\\gibs\\gibmetal2.abc",
};

char *szMetalSkins[NUM_METAL_GIBS] = 
{
	"skins\\gibs\\gibmetal1.dtx",
	"skins\\gibs\\gibmetal2.dtx",
};

//FLESH
char *szStoneGibs[NUM_STONE_GIBS] = 
{
	"models\\gibs\\giblarge2.abc",
	"models\\gibs\\giblarge3.abc"
};

char *szStoneSkins[NUM_STONE_GIBS] = 
{
	"skins\\gibs\\giblarge2.dtx",
	"skins\\gibs\\giblarge3.dtx"
};

//WOOD
char *szWoodGibs[NUM_WOOD_GIBS] = 
{
	"models\\gibs\\debriswood1.abc",
	"models\\gibs\\debriswood2.abc",
	"models\\gibs\\debriswood3.abc"
};

char *szWoodSkins[NUM_WOOD_GIBS] = 
{
	"skins\\gibs\\debriswood1.dtx",
	"skins\\gibs\\debriswood2.dtx",
	"skins\\gibs\\debriswood3.dtx"
};

//GLASS
char *szGlassGibs[NUM_GLASS_GIBS] = 
{
	"models\\gibs\\gibglass1.abc",
	"models\\gibs\\gibglass2.abc",
};

char *szGlassSkins[NUM_GLASS_GIBS] = 
{
	"skins\\gibs\\gibglass1.dtx",
	"skins\\gibs\\gibglass2.dtx",
};

BEGIN_CLASS(CGib)
	ADD_DESTRUCTABLE_AGGREGATE()
	ADD_STRINGPROP(InitFilename, "")
	ADD_STRINGPROP(InitSkin, "")
	ADD_LONGINTPROP(InitFlags, (FLAG_VISIBLE | FLAG_RAYHIT | FLAG_GRAVITY | FLAG_SHADOW))
	ADD_STRINGPROP(InitAnim,"")
	ADD_REALPROP(HitPoints, 20.0f)
	ADD_REALPROP(ObjectMass, 10.0f)
	ADD_BOOLPROP(Kickable, DTRUE)
END_CLASS_DEFAULT(CGib, B2BaseClass, NULL, NULL)

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CGib::CGib() : B2BaseClass(OT_MODEL)
{
	CServerDE* pServerDE = GetServerDE();

	AddAggregate(&m_damage);

	m_szInitAnim[0] = '\0';
	m_fMass = 3.0f;
	m_fHitPoints = 10.0f;

	m_dwGibType = 0;
	m_bGibbed = DFALSE;

	m_fPitchVel = pServerDE->Random(-MATH_CIRCLE, MATH_CIRCLE) / 3.0f;
	m_fYawVel	= pServerDE->Random(-MATH_CIRCLE, MATH_CIRCLE) / 3.0f;
	m_fRollVel	= pServerDE->Random(-MATH_CIRCLE, MATH_CIRCLE) / 3.0f;
	m_fPitch = 0.0;
	m_fYaw = 0.0;
	m_fRoll = 0.0;
	m_fLastTime = 0.0;

	m_hSmokeTrail = DNULL;
	m_hBloodTrail = DNULL;
	m_bAddSmokeTrail = DFALSE;
	m_bAddBloodTrail = DFALSE;

	m_bPlaySplat = DFALSE;

	VEC_INIT(m_vLastPos);

	m_hCorpseClass = DNULL;
	m_dwSurfType = SURFTYPE_FLESH;	// Default surface type
	m_nBounceCount = 0;

	m_bKickable = DTRUE;

	m_nAxisAlign = 0;

	m_bFirstUpdate = DTRUE;

	m_fRemoveTime = 0;

	m_fRotateTime = 0;
	m_bAddBloodSpurt = DFALSE;
}


CGib::~CGib()
{
	CServerDE* pServerDE = GetServerDE();
	if (!pServerDE) return;

	if (m_hSmokeTrail)
		pServerDE->RemoveObject(m_hSmokeTrail);

	if (m_hBloodTrail)
		pServerDE->RemoveObject(m_hBloodTrail);
}

// --------------------------------------------------------------------------- //
//
//	ROUTINE:	CGib::EngineMessageFn()
//
//	PURPOSE:	Handler for engine messages
//
// --------------------------------------------------------------------------- //

DDWORD CGib::EngineMessageFn(DDWORD messageID, void *pData, float fData)
{
	switch(messageID)
	{
		case MID_PRECREATE:
		{
			DDWORD dwRet = B2BaseClass::EngineMessageFn(messageID, pData, fData);

			if (fData == 1.0f)
				ReadProp((ObjectCreateStruct*)pData);

			PostPropRead((ObjectCreateStruct*)pData);

			return dwRet;
		}

		case MID_INITIALUPDATE:
		{
			InitialUpdate((DVector *)pData);
			break;
		}

		case MID_UPDATE:
		{
			if(m_dwGibType & GIB_SMALL || m_damage.IsDead())
				g_pServerDE->RemoveObject( m_hObject );
			else
				if (!Update())
					g_pServerDE->RemoveObject( m_hObject );
			break;
		}

		case MID_TOUCHNOTIFY:
		{
			HandleTouch((HOBJECT)pData, fData);
			break;
		}

	}

	return B2BaseClass::EngineMessageFn(messageID, pData, fData);
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CGib::ObjectMessageFn
//
//	PURPOSE:	Handle object-to-object messages
//
// ----------------------------------------------------------------------- //

DDWORD CGib::ObjectMessageFn( HOBJECT hSender, DDWORD messageID, HMESSAGEREAD hRead )
{
	CServerDE* g_pServerDE = GetServerDE();
	if (!g_pServerDE) return 0;

	switch(messageID)
	{
		case MID_DAMAGE:
		{
			DVector vDir;
				
			g_pServerDE->ReadFromMessageVector(hRead, &vDir);
			g_pServerDE->ResetRead(hRead);	// reset since I'm not reading all items.

			// Let Destructable aggregate do its job first...
			DDWORD ret = B2BaseClass::ObjectMessageFn(hSender, messageID, hRead);
			
			Damage(vDir);
			
			return ret;
		}

		default : break;
	}

	return B2BaseClass::ObjectMessageFn(hSender, messageID, hRead);
}

// --------------------------------------------------------------------------- //
//
//	ROUTINE:	CGib::ReadProp()
//
//	PURPOSE:	Reads properties
//
// --------------------------------------------------------------------------- //

DBOOL CGib::ReadProp(ObjectCreateStruct *pStruct)
{
	CServerDE* pServerDE = GetServerDE();
	if (!pServerDE || !pStruct) return DFALSE;

	char buf[MAX_CS_FILENAME_LEN];
	GenericProp genProp;

	if (pServerDE->GetPropGeneric("Kickable", &genProp) == DE_OK)
	{
		m_bKickable = genProp.m_Bool;
	}

	pServerDE->GetPropReal("HitPoints", &m_fHitPoints);
	pServerDE->GetPropReal("ObjectMass", &m_fMass);

	// Read in the destroyed object props.
	buf[0] = '\0';
	pServerDE->GetPropString("InitFilename", buf, MAX_CS_FILENAME_LEN);
	if (buf[0]) 
	{
		_mbscpy((unsigned char*)pStruct->m_Filename, (const unsigned char*)buf);
		m_dwSurfType = SURFTYPE_PLASTIC;
	}

	buf[0] = '\0';
	pServerDE->GetPropString("InitSkin", buf, MAX_CS_FILENAME_LEN);
	if (buf[0]) _mbscpy((unsigned char*)pStruct->m_SkinName, (const unsigned char*)buf);

	long nLongVal;
	if (pServerDE->GetPropLongInt("InitFlags", &nLongVal) == DE_OK)
		pStruct->m_Flags = (DDWORD)nLongVal;

	buf[0] = '\0';
	pServerDE->GetPropString("InitAnim", buf, MAX_CS_FILENAME_LEN);
	if (buf[0]) _mbscpy((unsigned char*)m_szInitAnim, (const unsigned char*)buf);

	return DTRUE;
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	PostPropRead()
//
//	PURPOSE:	Update properties
//
// ----------------------------------------------------------------------- //

void CGib::PostPropRead(ObjectCreateStruct *pStruct)
{
	if (!pStruct) return;

	pStruct->m_Flags = FLAG_VISIBLE | FLAG_RAYHIT | FLAG_GRAVITY | FLAG_TOUCH_NOTIFY;

	m_dwGibType = pStruct->m_UserData;

	if(pStruct->m_UserData & GIB_CORPSE)
	{
		m_dwSurfType = SURFTYPE_FLESH;

		m_fMass = 10.0f;
		m_fHitPoints = 50.0f;
	}
	else if(pStruct->m_UserData & GIB_HEAD || pStruct->m_UserData & GIB_ARM || pStruct->m_UserData & GIB_LEG)
	{
		m_fMass = 3.0f;
		m_fHitPoints = 10.0f;
	}
	else
	{
		if(pStruct->m_UserData & GIB_METAL)
		{
			m_dwSurfType = SURFTYPE_METAL;

			int nModel = (int)g_pServerDE->Random(0,NUM_METAL_GIBS - 1);

			if(pStruct->m_Filename[0] == DNULL)
				_mbscpy( (unsigned char*)pStruct->m_Filename, (const unsigned char*)szMetalGibs[nModel]);

			if(pStruct->m_SkinName[0] == DNULL)
				_mbscpy( (unsigned char*)pStruct->m_SkinName, (const unsigned char*)szMetalSkins[nModel]);
		}
		else if(pStruct->m_UserData & GIB_GLASS)
		{
			m_dwSurfType = SURFTYPE_GLASS;

			int nModel = (int)g_pServerDE->Random(0,NUM_GLASS_GIBS - 1);

			if(pStruct->m_Filename[0] == DNULL)
				_mbscpy( (unsigned char*)pStruct->m_Filename, (const unsigned char*)szGlassGibs[nModel]);

			if(pStruct->m_SkinName[0] == DNULL)
				_mbscpy( (unsigned char*)pStruct->m_SkinName, (const unsigned char*)szGlassSkins[nModel]);
		}
		else if(pStruct->m_UserData & GIB_WOOD)
		{
			m_dwSurfType = SURFTYPE_WOOD;

			int nModel = (int)g_pServerDE->Random(0,NUM_WOOD_GIBS - 1);

			if(pStruct->m_Filename[0] == DNULL)
				_mbscpy( (unsigned char*)pStruct->m_Filename, (const unsigned char*)szWoodGibs[nModel]);

			if(pStruct->m_SkinName[0] == DNULL)
				_mbscpy( (unsigned char*)pStruct->m_SkinName, (const unsigned char*)szWoodSkins[nModel]);
		}
		else if(pStruct->m_UserData & GIB_STONE)
		{
			m_dwSurfType = SURFTYPE_STONE;

			int nModel = (int)g_pServerDE->Random(0,NUM_STONE_GIBS - 1);

			if(pStruct->m_Filename[0] == DNULL)
				_mbscpy( (unsigned char*)pStruct->m_Filename, (const unsigned char*)szStoneGibs[nModel]);

			if(pStruct->m_SkinName[0] == DNULL)
				_mbscpy( (unsigned char*)pStruct->m_SkinName, (const unsigned char*)szStoneSkins[nModel]);
		}
		else if(pStruct->m_UserData & GIB_FLESH)
		{
			m_dwSurfType = SURFTYPE_FLESH;

			int nModel = (int)g_pServerDE->Random(0,NUM_FLESH_GIBS - 1);

			if(pStruct->m_Filename[0] == DNULL)
				_mbscpy( (unsigned char*)pStruct->m_Filename, (const unsigned char*)szFleshGibs[nModel]);

			if(pStruct->m_SkinName[0] == DNULL)
				_mbscpy( (unsigned char*)pStruct->m_SkinName, (const unsigned char*)szFleshSkins[nModel]);
		}

		m_fMass = 3.0f;
		m_fHitPoints = 10.0f;
	}

	// Is it smoking?
	if (pStruct->m_UserData & GIB_SMOKETRAIL)
	{
		m_bAddSmokeTrail = DTRUE;
	}

	if(pStruct->m_UserData & (GIB_BLOODTRAIL | GIB_FLESH))
	{
		m_bAddBloodTrail = DTRUE;
	}

	return;
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CGib::InitialUpdate()
//
//	PURPOSE:	Handle initial update
//
// ----------------------------------------------------------------------- //

void CGib::InitialUpdate(DVector *pMovement)
{
	CServerDE* pServerDE = GetServerDE();

	m_damage.Init( m_hObject );

	// Setup damage stats...
	m_damage.SetMass( m_fMass );
	m_damage.SetHitPoints( m_fHitPoints );
	m_damage.SetMaxHitPoints( m_fHitPoints );
	m_damage.SetArmorPoints( 0.0f );
	m_damage.SetMaxArmorPoints( 0.0f );
	m_damage.SetApplyDamagePhysics(DTRUE);

	pServerDE->SetForceIgnoreLimit(m_hObject, 0.1f);

	if(m_szInitAnim[0])		//SCHLEGZ 3/6/98 12:30:43 PM: allow for setting corpses
	{
		pServerDE->SetModelAnimation(m_hObject,pServerDE->GetAnimIndex(m_hObject,m_szInitAnim));
	}
	pServerDE->SetModelLooping(m_hObject, DFALSE);

	if (m_bKickable)
	{
		DVector vDims;
		pServerDE->GetModelAnimUserDims(m_hObject, &vDims, pServerDE->GetModelAnimation(m_hObject));
		DFLOAT fMax = vDims.x;
		if (vDims.y > fMax) fMax = vDims.y;
		if (vDims.z > fMax) fMax = vDims.z;
		VEC_SET(vDims, fMax, fMax, fMax);

		pServerDE->SetObjectDims(m_hObject, &vDims);
	}

	if (m_bAddSmokeTrail)
	{
		ObjectCreateStruct theStruct;
		INIT_OBJECTCREATESTRUCT(theStruct);

		pServerDE->GetObjectPos(m_hObject, &theStruct.m_Pos);
		HCLASS hClass = pServerDE->GetClass("CClientSmokeTrail");

		CClientSmokeTrail* pTrail = DNULL;

⌨️ 快捷键说明

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