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

📄 trigger.cpp

📁 Blood 2全套源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	if (m_bActive && m_bTouchActivate && ValidateSender(hObj))
	{
		m_hLastSender = hObj;

		// If this is a counter trigger, determine if we can activate or not...

		if (++m_nCurrentActivation < m_nActivationCount)
		{
			return;
		}
		else
		{
			m_nCurrentActivation = 0;
		}

		PlayActivationSound();

		// Make us wait a bit before we can be triggered again...

		if (m_fMaxTriggerMessageDelay)
		{
			m_fDelayStartTime = g_pServerDE->GetTime();

			g_pServerDE->SetNextUpdate(m_hObject, 0.01f);
			for (int i = 0; i < MAX_TRIGGER_MESSAGES; i++)
			{
				if (m_fTriggerMessageDelay[i])
					m_bDelay[i] = DTRUE;
				else if (m_hstrTargetName[i] && m_hstrMessageName[i])	// Else send the message now
					SendMessage(i);
			}
//			m_bDelay = DTRUE;
		}
		else
		{
			SendMessages();
			g_pServerDE->SetNextUpdate(m_hObject, m_fTriggerResetTime);
		}

		m_bActive = DFALSE;
	}
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	Trigger::InitialUpdate
//
//	PURPOSE:	Initial update
//
// ----------------------------------------------------------------------- //

DBOOL Trigger::InitialUpdate(DVector *position)
{
	if (!g_pServerDE) return DFALSE;

	g_pServerDE->SetObjectDims(m_hObject, &m_vDims);
	g_pServerDE->SetObjectFlags(m_hObject, FLAG_TOUCH_NOTIFY);

	// My object touch notification will trigger new updates
	// until then, I don't care...
	
	// Mark this object as savable
	DDWORD dwFlags = g_pServerDE->GetObjectUserFlags(m_hObject);
	dwFlags |= USRFLG_SAVEABLE;
	g_pServerDE->SetObjectUserFlags(m_hObject, dwFlags);

	g_pServerDE->SetNextUpdate(m_hObject, 0.0f);

	return DTRUE;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	Trigger::Update
//
//	PURPOSE:	Handle Update
//
// ----------------------------------------------------------------------- //

DBOOL Trigger::Update(DVector *position)
{
	if (!g_pServerDE) return DFALSE;

	DBOOL bDelayed = DFALSE;

	// Trigger was delayed, send now
	for (int i=0; i < MAX_TRIGGER_MESSAGES; i++)
	{
		if (m_bDelay[i])
		{
			bDelayed = DTRUE;
		}
	}

	// Not waiting for any more delays, reset the trigger
	if (!bDelayed)
	{
		m_bActive = DTRUE;

		// My object touch notification will trigger new updates
		// until then, I don't care.
		g_pServerDE->SetNextUpdate(m_hObject, 0.0f);
		return DTRUE;
	}
	else
	{
		DFLOAT fTime = g_pServerDE->GetTime();
		bDelayed = DFALSE;

		for (int i=0; i < MAX_TRIGGER_MESSAGES; i++)
		{
			if (m_bDelay[i])
			{
				if (fTime >= m_fDelayStartTime + m_fTriggerMessageDelay[i])
				{
					SendMessage(i);
					m_bDelay[i] = DFALSE;
				}
				else 
					bDelayed = DTRUE;	// Keep track of messages not sent, for NextUpdate
			}
		}

		if (bDelayed)
		{
			g_pServerDE->SetNextUpdate(m_hObject, 0.01f);
		}
		else	// No more messages, start reset time
		{
			g_pServerDE->SetNextUpdate(m_hObject, m_fTriggerResetTime);
		}
	}

	return DTRUE;
}


// ------------------------------------------------------------ //
//
//	ROUTINE:	Trigger::EngineMessageFn
//
//	PURPOSE:	Handle engine messages
//
// ----------------------------------------------------------------------- //
DDWORD Trigger::EngineMessageFn(DDWORD messageID, void *pData, float fData)
{
	switch(messageID)
	{
		case MID_UPDATE:
		{
			if (!Update((DVector *)pData))
			{
				g_pServerDE->RemoveObject(m_hObject);
				return DFALSE;
			}

			break;
		}

		case MID_TOUCHNOTIFY:
		{
			ObjectTouch((HOBJECT)pData);
			break;
		}

		case MID_PRECREATE:
		{
			if (fData == PRECREATE_WORLDFILE || fData == PRECREATE_STRINGPROP)
			{
				ReadProp((ObjectCreateStruct*)pData);
			}
			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:	Trigger::ObjectMessageFn
//
//	PURPOSE:	Handle object messages
//
// ----------------------------------------------------------------------- //

DDWORD Trigger::ObjectMessageFn(HOBJECT hSender, DDWORD messageID, HMESSAGEREAD hRead)
{
	switch (messageID)
	{
		case MID_TRIGGER :
		{
			HandleTriggerMsg(hSender, hRead);
		}
		break;

		case MID_KEYQUERYRESPONSE:
		{
			HandleKeyQueryResponse(hSender, hRead);
		}
		break;
	}

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


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	Trigger::HandleKeyQueryResponse
//
//	PURPOSE:	Handle the MID_KEYQUERYRESPONSE message
//
// ----------------------------------------------------------------------- //

void Trigger::HandleKeyQueryResponse(HOBJECT hSender, HMESSAGEREAD hRead)
{
	CServerDE* pServerDE = GetServerDE();
	if (!pServerDE) return;

	HSTRING hItemName = g_pServerDE->ReadFromMessageHString(hRead);
	DBOOL	bHaveItem = (DBOOL)g_pServerDE->ReadFromMessageByte(hRead);

	// Check the key & locked status
	if (m_bLocked && bHaveItem && g_pServerDE->CompareStringsUpper(hItemName, m_hstrKeyName))
	{
		pServerDE->FreeString(hItemName);
		// unlock if necessary and send access granted or denied messages
		m_bLocked = DFALSE;
		
		if (m_hstrUnlockedMsg)
		{
			// send text message
		}
/*
		if (m_hstrUnlockedSound)
		{
			char *pSound = pServerDE->GetStringData(m_hstrUnlockedSound);
			if (!pSound) return;

			PlaySoundFromObject(hSender, pSound, 200.0f, SOUNDTYPE_MISC, SOUNDPRIORITY_HIGH);
		}
*/
	}
	else
	{
		pServerDE->FreeString(hItemName);
		if (m_hstrLockedMsg)
		{
			// send text message
		}
	}
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	Trigger::HandleTriggerMsg
//
//	PURPOSE:	Handle object messages
//
// ----------------------------------------------------------------------- //

void Trigger::HandleTriggerMsg(HOBJECT hSender, HMESSAGEREAD hRead)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !m_bActive) return;

	HSTRING hMsg = pServerDE->ReadFromMessageHString(hRead);
	char *pMsg = pServerDE->GetStringData(hMsg);
	
	if (pMsg)
	{
		if (_mbsicmp((const unsigned char*)pMsg, (const unsigned char*)g_szTrigger) == 0 && ValidateSender(hSender))
		{
			// If this is a counter trigger, determine if we can activate or not...

			if (++m_nCurrentActivation < m_nActivationCount)
			{
				pServerDE->FreeString(hMsg);
				return;
			}
			else
			{
				m_nCurrentActivation = 0;
			}

			PlayActivationSound();
	
			m_hLastSender = hSender;
			if (m_fMaxTriggerMessageDelay)
			{
				m_fDelayStartTime = g_pServerDE->GetTime();
	
				g_pServerDE->SetNextUpdate(m_hObject, 0.01f);
				for (int i = 0; i < MAX_TRIGGER_MESSAGES; i++)
				{
					if (m_fTriggerMessageDelay[i])
						m_bDelay[i] = DTRUE;
					else if (m_hstrTargetName[i] && m_hstrMessageName[i])	// Else send the message now
						SendMessage(i);
				}
			}
			else
			{
				SendMessages();
				g_pServerDE->SetNextUpdate(m_hObject, m_fTriggerResetTime);
			}

			m_bActive = DFALSE;
		}
		// reset the trigger: Set active, and clear the next update if any
		else if (_mbsicmp((const unsigned char*)pMsg, (const unsigned char*)g_szReset) == 0)
		{
			m_bActive = DTRUE;
			g_pServerDE->SetNextUpdate(m_hObject, 0.0f);
		}
		else if (_mbsicmp((const unsigned char*)pMsg, (const unsigned char*)g_szLock) == 0)
		{
			m_bLocked = DTRUE;
			g_pServerDE->SetNextUpdate(m_hObject, 0.0f);
		}
		else if (_mbsicmp((const unsigned char*)pMsg, (const unsigned char*)g_szUnLock) == 0)
		{
			if (m_hstrUnlockedSound && m_bLocked)
			{
				char *pSound = pServerDE->GetStringData(m_hstrUnlockedSound);
				if (!pSound)
				{
					g_pServerDE->FreeString( hMsg );
					return;
				}
				
				if (GetGameType() == GAMETYPE_ACTION && g_pPlayerObj)
				{
					HSTRING hstr = g_pServerDE->FormatString(IDS_GENERAL_UNLOCKED);
					g_pPlayerObj->SendConsoleMessage(g_pServerDE->GetStringData(hstr));
					g_pServerDE->FreeString(hstr);
//					g_pPlayerObj->SendConsoleMessage("Unlocked!");
				}
				else
				{
					PlaySoundFromObject(hSender, pSound, 200.0f, SOUNDPRIORITY_MISC_HIGH);
				}
			}
			m_bLocked = DFALSE;
			g_pServerDE->SetNextUpdate(m_hObject, 0.0f);
		}
	}
	pServerDE->FreeString(hMsg);
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	Trigger::SendMessage
//
//	PURPOSE:	Sends the trigger message for slot nSlot
//
// ----------------------------------------------------------------------- //
void Trigger::SendMessage(int nSlot)
{
	if (m_hstrTargetName[nSlot] && m_hstrMessageName[nSlot])
	{
		SendTriggerMsgToObjects(this, m_hstrTargetName[nSlot], m_hstrMessageName[nSlot]);
	}
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	Trigger::SendMessages
//
//	PURPOSE:	Sends the trigger messages
//
// ----------------------------------------------------------------------- //

void Trigger::SendMessages()
{
	if (m_bSending) return;
	m_bSending = DTRUE;

	for (int i=0; i < MAX_TRIGGER_MESSAGES; i++)
	{
		if (m_hstrTargetName[i] && m_hstrMessageName[i])
		{
			SendTriggerMsgToObjects(this, m_hstrTargetName[i], m_hstrMessageName[i]);
		}
	}

	m_bSending = DFALSE;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	Trigger::PlayActivationSound
//
//	PURPOSE:	Plays the activation sound, if any
//
// ----------------------------------------------------------------------- //
void Trigger::PlayActivationSound()
{
	if (!m_hstrActivationSound || !g_pServerDE) return;

	char* pSound = g_pServerDE->GetStringData(m_hstrActivationSound);
	if (pSound && pSound[0] != '\0')
	{
		PlaySoundFromObject(m_hObject, pSound, m_fSoundRadius, SOUNDPRIORITY_MISC_MEDIUM);
	}
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	Trigger::ValidateSender
//
//	PURPOSE:	Determines if the object triggering us is allowed to.
//
// ----------------------------------------------------------------------- //
DBOOL Trigger::ValidateSender(HOBJECT hObj)
{
	DBOOL	bRetVal = DFALSE;
	HCLASS	hAIObj		= g_pServerDE->GetClass("CBaseCharacter");
	HCLASS  hPlayerObj	= g_pServerDE->GetClass("CPlayerObj");
	HCLASS	hTriggerObj	= g_pServerDE->GetClass("Trigger");
	HCLASS	hObjClass	= g_pServerDE->GetObjectClass(hObj);

⌨️ 快捷键说明

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