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

📄 flagobjects.cpp

📁 Blood 2全套源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
;
;	 MODULE:		FLAGOBJECTS (.CPP)
;
;	PURPOSE:		Flag Objects for CTF
;
;	HISTORY:		12/30/98 [blg] This file was created
;
;	COMMENT:		Copyright (c) 1998, Monolith Productions Inc.
;
****************************************************************************/

// Includes...

#include "FlagObjects.h"
#include "ObjectUtilities.h"
#include "Spawner.h"
#include "StdIo.h"
#include <mbstring.h>
#include "SoundTypes.h"


// Statics...

static FlagObject* s_pTeam1Flag = NULL;
static FlagObject* s_pTeam2Flag = NULL;


// Functions...

// *********************************************************************** //
// FlagObject

BEGIN_CLASS(FlagObject)

	ADD_STRINGPROP(ObjectName, "CTF_Flag")					// Item name
	ADD_LONGINTPROP(TeamID, 0)								// Team ID (1 or 2)

END_CLASS_DEFAULT(FlagObject, B2BaseClass, NULL, NULL)


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	FlagObject::~FlagObject
//
//	PURPOSE:	Destructor
//
// ----------------------------------------------------------------------- //

FlagObject::~FlagObject()
{
	if (g_pServerDE && m_hFlagGrabString)
	{
		g_pServerDE->FreeString(m_hFlagGrabString);
		m_hFlagGrabString = DNULL;
	}

	if (this == s_pTeam1Flag)
	{
		s_pTeam1Flag = NULL;
	}

	if (this == s_pTeam2Flag)
	{
		s_pTeam2Flag = NULL;
	}
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	FlagObject::EngineMessageFn
//
//	PURPOSE:	Handler for engine messages
//
// ----------------------------------------------------------------------- //

DDWORD FlagObject::EngineMessageFn(DDWORD messageID, void *pData, DFLOAT fData)
{
	// Handle the engine messages we're interested in...

	switch(messageID)
	{
		case MID_PRECREATE:
		{
			if (fData == PRECREATE_WORLDFILE || fData == PRECREATE_STRINGPROP)
			{
				ReadProp((ObjectCreateStruct*)pData);
			}

			PostPropRead((ObjectCreateStruct*)pData);

			break;
		}

		case MID_INITIALUPDATE:
		{
			OnInitialUpdate(pData, fData);
			break;
		}

		case MID_TOUCHNOTIFY:
		{
			if (!IsWithPlayer())
			{
				OnTouchNotify((HOBJECT)pData);
			}
			break;
		}

		case MID_UPDATE:
		{
			if (IsOnGround())
			{
				ReturnToFlagStand();
			}
			break;
		}
	}

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


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	FlagObject::ReadProp
//
//	PURPOSE:	Reads FlagObject properties
//
// ----------------------------------------------------------------------- //

DBOOL FlagObject::ReadProp(ObjectCreateStruct *pStruct)
{
	GenericProp genProp;

	if (g_pServerDE->GetPropGeneric("TeamID", &genProp) == DE_OK)
	{
		m_nTeamID = (int)genProp.m_Long;
	}

	return DTRUE;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	FlagStand::PostPropRead()
//
//	PURPOSE:	Updates the properties now that they have been read
//
// ----------------------------------------------------------------------- //

void FlagObject::PostPropRead(ObjectCreateStruct* pStruct)
{
	// Sanity checks...

	if (!pStruct) return;


	// Set the flags we want...

	pStruct->m_Flags |= FLAG_TOUCH_NOTIFY | FLAG_VISIBLE;
	pStruct->m_Flags &= ~FLAG_GRAVITY;

	g_pServerDE->SetNextUpdate(m_hObject, 0.001f);


	// Set the model filename

	if (m_nTeamID == 1)
	{
		char* pFilename = "Models\\WorldObjects\\flagblue.abc";
		_mbscpy((unsigned char*)pStruct->m_Filename, (const unsigned char*)pFilename);
	}
	else if (m_nTeamID == 2)
	{
		char* pFilename = "Models\\WorldObjects\\flagred.abc";
		_mbscpy((unsigned char*)pStruct->m_Filename, (const unsigned char*)pFilename);
	}
	

	// Set the skin filename

	if (m_nTeamID == 1)
	{
		char* pSkin = "Skins\\WorldObjects\\flagblue.dtx";	
		_mbscpy((unsigned char*)pStruct->m_SkinName, (const unsigned char*)pSkin);
	}
	else if (m_nTeamID = 2)
	{
		char* pSkin = "Skins\\WorldObjects\\flagred.dtx";	
		_mbscpy((unsigned char*)pStruct->m_SkinName, (const unsigned char*)pSkin);
	}
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	FlagObject::OnInitialUpdate()
//
//	PURPOSE:	Handles the MID_INITIALUPDATE engine message
//
// ----------------------------------------------------------------------- //

void FlagObject::OnInitialUpdate(void* pData, DFLOAT fData)
{
	// Set the dims...

	DVector vDims;

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

	if (g_pServerDE->SetObjectDims2(m_hObject, &vDims) == DE_ERROR)
	{
		g_pServerDE->SetObjectDims(m_hObject, &vDims);
	}


	// Save our initial flag stand position...

	g_pServerDE->GetObjectPos(m_hObject, &m_vStand);
	g_pServerDE->GetObjectRotation(m_hObject, &m_rStand);

	m_bInStand    = DTRUE;
	m_bOnGround   = DFALSE;
	m_bWithPlayer = DFALSE;


	// Set our static pointer...

	if (m_nTeamID == TEAM_1)
	{
		s_pTeam1Flag = this;
	}

	if (m_nTeamID == TEAM_2)
	{
		s_pTeam2Flag = this;
	}


	// Create our trigger string if necessary...

	if (!m_hFlagGrabString)
	{
		m_hFlagGrabString = g_pServerDE->CreateString("flaggrab");
	}
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	FlagObject::ObjectMessageFn
//
//	PURPOSE:	Handle messages from objects
//
// ----------------------------------------------------------------------- //

DDWORD FlagObject::ObjectMessageFn(HOBJECT hSender, DDWORD messageID, HMESSAGEREAD hRead)
{
	switch (messageID)
	{
		case MID_TRIGGER:
		{
			// Get the trigger name...

			HSTRING hMsg = g_pServerDE->ReadFromMessageHString(hRead);
			if (hMsg)
			{
				char* sMsg = g_pServerDE->GetStringData(hMsg);
				if (sMsg)
				{
					// Check if we should return to the flag stand...

					if (_mbsicmp((const unsigned char*)sMsg, (const unsigned char*)"return") == 0)
					{
						ReturnToFlagStand();
					}
				}

				g_pServerDE->FreeString(hMsg);
			}

			break;
		}

		default: break;
	}

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


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	FlagObject::SetPos
//
//	PURPOSE:	Sets the flags position to the given value
//
// ----------------------------------------------------------------------- //

void FlagObject::SetPos(DVector* pPos)
{
	// Sanity checks...

	if (!pPos) return;
	if (!g_pServerDE) return;


	// Set the objects position...

	g_pServerDE->SetObjectPos(m_hObject, pPos);
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	FlagObject::ReturnToFlagStand
//
//	PURPOSE:	Moves the flag back to it's original flag stand position
//
// ----------------------------------------------------------------------- //

void FlagObject::ReturnToFlagStand()
{
	// If we're already in our flag stand, just return...

	if (m_bInStand) return;


	// Set our "stand" position...

	DRotation rTemp;
	g_pServerDE->SetupEuler(&rTemp, 1, 1, 1);
	g_pServerDE->SetObjectRotation(m_hObject, &rTemp);

	g_pServerDE->SetObjectPos(m_hObject, &m_vStand);
	g_pServerDE->SetObjectRotation(m_hObject, &m_rStand);


	// Play a cool respawn sound...

	char* sSound = "sounds_multipatch\\CtfFlagRespawn.WAV";
	PlaySoundFromPos(&m_vStand, sSound, 2000.0f, SOUNDPRIORITY_MISC_MEDIUM, DFALSE, DFALSE, DFALSE);


	// Flag that we are back in our stand...

	m_bInStand    = DTRUE;
	m_bOnGround   = DFALSE;
	m_bWithPlayer = DFALSE;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	FlagObject::GiveToPlayer
//
//	PURPOSE:	Gives the flag to a player
//
// ----------------------------------------------------------------------- //

void FlagObject::GiveToPlayer()
{
	// Set all the flags such that we are being carried by a player...

	m_bInStand    = DFALSE;
	m_bOnGround   = DFALSE;
	m_bWithPlayer = DTRUE;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	FlagObject::DropToGround()
//
//	PURPOSE:	Drops the flag to the ground
//
// ----------------------------------------------------------------------- //

void FlagObject::DropToGround()
{
	// Move the flag to the ground...

⌨️ 快捷键说明

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