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

📄 detailsprite.cpp

📁 Blood 2全套源码
💻 CPP
字号:
// ----------------------------------------------------------------------- //
//
// MODULE  : DetailSprite.cpp
//
// PURPOSE : DetailSprite class - implementation
//
// CREATED : 2/28/98
//
// ----------------------------------------------------------------------- //

#include "cpp_server_de.h"
#include "DetailSprite.h"
#include "SharedDefs.h"
#include "ClientServerShared.h"
#include <mbstring.h>



BEGIN_CLASS(DetailSprite)
	ADD_STRINGPROP(Filename, "")
	ADD_REALPROP(ScaleX, 1.0f)
	ADD_REALPROP(ScaleY, 1.0f)
	ADD_BOOLPROP(FlushWithWorld, DFALSE)
	ADD_BOOLPROP(Rotatable, DTRUE)
	ADD_BOOLPROP(Chromakey, DFALSE)
	ADD_BOOLPROP(Repeat, DFALSE)
	ADD_LONGINTPROP(RepeatX, 1)
	ADD_LONGINTPROP(RepeatY, 1)
	ADD_REALPROP(SpacingX, 0.0f)
	ADD_REALPROP(SpacingY, 0.0f)
END_CLASS_DEFAULT(DetailSprite, B2BaseClass, NULL, NULL)


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	DetailSprite::DetailSprite
//
//	PURPOSE:	Initialize
//
// ----------------------------------------------------------------------- //

DetailSprite::DetailSprite() : B2BaseClass(OT_SPRITE)
{
	VEC_SET(m_vScale, 1.0f, 1.0f, 1.0f);
	m_bFlushWithWorld = DFALSE;
	m_bRotatable	  = DFALSE;
	m_bChromaKey      = DFALSE;
	m_hstrFilename	  = DNULL;
	m_bRepeat	      = DFALSE;
	m_dwRepeatX		  = 1;
	m_dwRepeatY		  = 1;
	m_fSpacingX		  = 0.0f;
	m_fSpacingY		  = 0.0f;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	DetailSprite::~DetailSprite
//
//	PURPOSE:	Destructor
//
// ----------------------------------------------------------------------- //

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

	if (m_hstrFilename)
	{
		pServerDE->FreeString(m_hstrFilename);
	}
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	DetailSprite::EngineMessageFn
//
//	PURPOSE:	Handle engine messages
//
// ----------------------------------------------------------------------- //

DDWORD DetailSprite::EngineMessageFn(DDWORD messageID, void *pData, DFLOAT fData)
{
	switch(messageID)
	{
		case MID_PRECREATE:
		{
			CServerDE* pServerDE = BaseClass::GetServerDE();
			if (!pServerDE) break;

			if (fData == PRECREATE_WORLDFILE || fData == PRECREATE_STRINGPROP)
			{
				ReadProp((ObjectCreateStruct *)pData);

				ObjectCreateStruct* pStruct = (ObjectCreateStruct*)pData;
				if (pStruct)
				{
					pStruct->m_SkinName[0] = '\0';
					pStruct->m_NextUpdate = 0.1f;
					VEC_COPY(pStruct->m_Scale, m_vScale)

					pStruct->m_Flags |= FLAG_VISIBLE;

					if (m_bRotatable || m_bFlushWithWorld)
					{
						pStruct->m_Flags |= FLAG_ROTATEABLESPRITE;
					}

					if (m_bChromaKey)
					{
						pStruct->m_Flags |= FLAG_SPRITECHROMAKEY;
					}

					if (m_hstrFilename)
					{
						char* pFilename = pServerDE->GetStringData(m_hstrFilename);
						if (pFilename)
						{
							_mbscpy((unsigned char*)pStruct->m_Filename, (const unsigned char*)pFilename);
						}
					}
				}
			}
		}
		break;

		case MID_INITIALUPDATE:
		{
			if (fData != INITIALUPDATE_SAVEGAME)
				InitialUpdate((DVector *)pData);
		}
		break;

		case MID_SAVEOBJECT:
			Save((HMESSAGEWRITE)pData, (DDWORD)fData);
			break;

		case MID_LOADOBJECT:
			Load((HMESSAGEREAD)pData, (DDWORD)fData);
			break;

		default : break;
	}


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


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	DetailSprite::ReadProp()
//
//	PURPOSE:	Update Properties
//
// ----------------------------------------------------------------------- //

void DetailSprite::ReadProp(ObjectCreateStruct *pStruct)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !pStruct) return;

	char buf[MAX_CS_FILENAME_LEN];

	buf[0] = '\0';
	pServerDE->GetPropString("Filename", buf, MAX_CS_FILENAME_LEN);
	if (buf[0]) m_hstrFilename = pServerDE->CreateString(buf);

	pServerDE->GetPropReal("ScaleX", &m_vScale.x);
	pServerDE->GetPropReal("ScaleY", &m_vScale.y);
	pServerDE->GetPropBool("Rotatable", &m_bRotatable);
	pServerDE->GetPropBool("FlushWithWorld", &m_bFlushWithWorld);
	pServerDE->GetPropBool("ChromaKey", &m_bChromaKey);
	pServerDE->GetPropBool("Repeat", &m_bRepeat);
	pServerDE->GetPropReal("SpacingX", &m_fSpacingX);
	pServerDE->GetPropReal("SpacingY", &m_fSpacingY);
	long nLongVal;
	pServerDE->GetPropLongInt("RepeatX", &nLongVal);
	m_dwRepeatX = nLongVal;
	pServerDE->GetPropLongInt("RepeatY", &nLongVal);
	m_dwRepeatY = nLongVal;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	DetailSprite::InitialUpdate
//
//	PURPOSE:	Do initial updating
//
// ----------------------------------------------------------------------- //

DBOOL DetailSprite::InitialUpdate(DVector*)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !m_hObject) return DFALSE;

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

	// Mark this object as savable
	DDWORD dwFlags = pServerDE->GetObjectUserFlags(m_hObject);
	dwFlags |= USRFLG_SAVEABLE;
	pServerDE->SetObjectUserFlags(m_hObject, dwFlags);

	if (m_bFlushWithWorld)
	{
		// Align the sprite to the surface directly along the forward vector

		DRotation rRot;
		DVector vPos, vU, vR, vF;
		pServerDE->GetObjectPos(m_hObject, &vPos);
		pServerDE->GetObjectRotation(m_hObject, &rRot);
		pServerDE->GetRotationVectors(&rRot, &vU, &vR, &vF);

		// Determine where on the surface to place the sprite...

		IntersectInfo ii;
		IntersectQuery iq;

		VEC_COPY(iq.m_From, vPos);
		VEC_COPY(iq.m_Direction, vF);
		iq.m_Flags	 = IGNORE_NONSOLID;
		iq.m_FilterFn = DNULL;

		if (pServerDE->CastRay(&iq, &ii))
		{
			DVector vTemp;
			VEC_COPY(vPos, ii.m_Point);
			VEC_COPY(vTemp, ii.m_Plane.m_Normal);
			VEC_COPY(vF, vTemp);

			// Place just in front of the wall

			VEC_MULSCALAR(vTemp, vTemp, 0.25f);
			VEC_ADD(vPos, vPos, vTemp);

			pServerDE->SetObjectPos(m_hObject, &vPos);
		}

		// Make more if desired
		if (m_bRepeat)
		{
			DVector vTmpPos, vTmpPos2;
			unsigned int x, y;

			VEC_COPY(vTmpPos, vPos);
			VEC_MULSCALAR(vU, vU, m_fSpacingY);
			VEC_MULSCALAR(vR, vR, m_fSpacingX);

			// Add in the Y direction;
			for (y = 1; y < m_dwRepeatY; y++)
			{
				VEC_ADD(vTmpPos, vTmpPos, vU);
				CreateAnotherSprite(&vTmpPos, &rRot);
			}

			// now repeat in the X (and Y) directions
			VEC_COPY(vTmpPos, vPos);
			for (x = 1; x < m_dwRepeatX; x++)
			{
				VEC_ADD(vTmpPos, vTmpPos, vR);
				VEC_COPY(vTmpPos2, vTmpPos);
				for (y = 0; y < m_dwRepeatY; y++)
				{
					CreateAnotherSprite(&vTmpPos2, &rRot);
					VEC_ADD(vTmpPos2, vTmpPos2, vU);
				}
			}
		}

	}

	return DTRUE;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	DetailSprite::CreateAnotherSprite
//
//	PURPOSE:	Creates another sprite the same as the current one.
//
// ----------------------------------------------------------------------- //

void DetailSprite::CreateAnotherSprite(DVector *pvPos, DRotation *prRot)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !m_hObject || !m_hstrFilename) return;

	ObjectCreateStruct ocStruct;
	INIT_OBJECTCREATESTRUCT(ocStruct);

	_mbscpy((unsigned char*)ocStruct.m_Filename, (const unsigned char*)pServerDE->GetStringData(m_hstrFilename));
	ROT_COPY(ocStruct.m_Rotation, *prRot);
	VEC_COPY(ocStruct.m_Pos, *pvPos);
	VEC_COPY(ocStruct.m_Scale, m_vScale);
	ocStruct.m_Flags = pServerDE->GetObjectFlags(m_hObject);

	HCLASS hClass = pServerDE->GetClass("DetailSprite");

	DetailSprite *pSprite = DNULL;

	// Something is seriously wrong if hClass is NULL ;)
	if (hClass)
	{
		pSprite = (DetailSprite*)pServerDE->CreateObject(hClass, &ocStruct);
	}
}


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

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

	pServerDE->WriteToMessageVector(hWrite, &m_vScale);
	pServerDE->WriteToMessageHString(hWrite, m_hstrFilename);
	pServerDE->WriteToMessageByte(hWrite, m_bRotatable);
	pServerDE->WriteToMessageByte(hWrite, m_bChromaKey);
	pServerDE->WriteToMessageByte(hWrite, m_bAlignedToWorld);
	pServerDE->WriteToMessageByte(hWrite, m_bFlushWithWorld);
}


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

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

	pServerDE->ReadFromMessageVector(hRead, &m_vScale);
	m_hstrFilename		= pServerDE->ReadFromMessageHString(hRead);
	m_bRotatable		= pServerDE->ReadFromMessageByte(hRead);
	m_bChromaKey		= pServerDE->ReadFromMessageByte(hRead);
	m_bAlignedToWorld	= pServerDE->ReadFromMessageByte(hRead);	
	m_bFlushWithWorld	= pServerDE->ReadFromMessageByte(hRead);
}



⌨️ 快捷键说明

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