📄 cinematictrigger.cpp
字号:
// ----------------------------------------------------------------------- //
//
// MODULE : CinematicTrigger.cpp
//
// PURPOSE : CinematicTrigger - Implementation
//
// CREATED : 10/6/97
//
// ----------------------------------------------------------------------- //
#include <stdio.h>
#include <string.h>
#include "CinematicTrigger.h"
#include "generic_msg_de.h"
#include "ObjectUtilities.h"
#include "ClientServerShared.h"
#include <mbstring.h>
#include "SoundTypes.h"
void SendTriggerMsgToObjects(LPBASECLASS pSender, HSTRING hName, HSTRING hMsg);
BEGIN_CLASS(CinematicTrigger)
ADD_REALPROP(Delay1, 0.0f)
ADD_STRINGPROP(Sound1, "")
ADD_STRINGPROP(WhoPlaysSound1, "")
ADD_STRINGPROP(StartSoundTriggerTarget1, "")
ADD_STRINGPROP(StartSoundTriggerMsg1, "")
ADD_REALPROP(Delay2, 0.0f)
ADD_STRINGPROP(Sound2, "")
ADD_STRINGPROP(WhoPlaysSound2, "")
ADD_STRINGPROP(StartSoundTriggerTarget2, "")
ADD_STRINGPROP(StartSoundTriggerMsg2, "")
ADD_REALPROP(Delay3, 0.0f)
ADD_STRINGPROP(Sound3, "")
ADD_STRINGPROP(WhoPlaysSound3, "")
ADD_STRINGPROP(StartSoundTriggerTarget3, "")
ADD_STRINGPROP(StartSoundTriggerMsg3, "")
ADD_REALPROP(Delay4, 0.0f)
ADD_STRINGPROP(Sound4, "")
ADD_STRINGPROP(WhoPlaysSound4, "")
ADD_STRINGPROP(StartSoundTriggerTarget4, "")
ADD_STRINGPROP(StartSoundTriggerMsg4, "")
ADD_REALPROP(Delay5, 0.0f)
ADD_STRINGPROP(Sound5, "")
ADD_STRINGPROP(WhoPlaysSound5, "")
ADD_STRINGPROP(StartSoundTriggerTarget5, "")
ADD_STRINGPROP(StartSoundTriggerMsg5, "")
ADD_REALPROP(Delay6, 0.0f)
ADD_STRINGPROP(Sound6, "")
ADD_STRINGPROP(WhoPlaysSound6, "")
ADD_STRINGPROP(StartSoundTriggerTarget6, "")
ADD_STRINGPROP(StartSoundTriggerMsg6, "")
ADD_REALPROP(Delay7, 0.0f)
ADD_STRINGPROP(Sound7, "")
ADD_STRINGPROP(WhoPlaysSound7, "")
ADD_STRINGPROP(StartSoundTriggerTarget7, "")
ADD_STRINGPROP(StartSoundTriggerMsg7, "")
ADD_REALPROP(Delay8, 0.0f)
ADD_STRINGPROP(Sound8, "")
ADD_STRINGPROP(WhoPlaysSound8, "")
ADD_STRINGPROP(StartSoundTriggerTarget8, "")
ADD_STRINGPROP(StartSoundTriggerMsg8, "")
ADD_REALPROP(Delay9, 0.0f)
ADD_STRINGPROP(Sound9, "")
ADD_STRINGPROP(WhoPlaysSound9, "")
ADD_STRINGPROP(StartSoundTriggerTarget9, "")
ADD_STRINGPROP(StartSoundTriggerMsg9, "")
ADD_REALPROP(Delay10, 0.0f)
ADD_STRINGPROP(Sound10, "")
ADD_STRINGPROP(WhoPlaysSound10, "")
ADD_STRINGPROP(StartSoundTriggerTarget10, "")
ADD_STRINGPROP(StartSoundTriggerMsg10, "")
ADD_BOOLPROP_FLAG(TypeActionMode, DFALSE, PF_GROUP6)
END_CLASS_DEFAULT(CinematicTrigger, B2BaseClass, NULL, NULL)
// ----------------------------------------------------------------------- //
//
// ROUTINE: CinematicTrigger::CinematicTrigger()
//
// PURPOSE: Initialize object
//
// ----------------------------------------------------------------------- //
CinematicTrigger::CinematicTrigger()
{
for (int i=0;i < MAX_CT_MESSAGES; i++)
{
m_fDelay[i] = 0.0f;
m_hstrSound[i] = DNULL;
m_hstrWhoPlaysSound[i] = DNULL;
m_hstrTargetName[i] = DNULL;
m_hstrMessageName[i] = DNULL;
}
m_nCurMessage = 0;
m_hCurSound = DNULL;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CinematicTrigger::~CinematicTrigger()
//
// PURPOSE: Deallocate object
//
// ----------------------------------------------------------------------- //
CinematicTrigger::~CinematicTrigger()
{
if (!g_pServerDE) return;
if (m_hCurSound)
{
g_pServerDE->KillSound(m_hCurSound);
m_hCurSound = DNULL;
}
for (int i=0; i < MAX_CT_MESSAGES; i++)
{
if (m_hstrSound[i])
{
g_pServerDE->FreeString(m_hstrSound[i]);
}
if (m_hstrWhoPlaysSound[i])
{
g_pServerDE->FreeString(m_hstrWhoPlaysSound[i]);
}
if (m_hstrTargetName[i])
{
g_pServerDE->FreeString(m_hstrTargetName[i]);
}
if (m_hstrMessageName[i])
{
g_pServerDE->FreeString(m_hstrMessageName[i]);
}
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CinematicTrigger::ReadProp
//
// PURPOSE: Set property value
//
// ----------------------------------------------------------------------- //
DBOOL CinematicTrigger::ReadProp(ObjectCreateStruct *pStruct)
{
if (!g_pServerDE) return DFALSE;
GenericProp genProp;
for (int i=0; i < MAX_CT_MESSAGES; i++)
{
char key[40];
sprintf(key, "Delay%d", i+1);
if (g_pServerDE->GetPropGeneric(key, &genProp) == DE_OK)
{
m_fDelay[i] = genProp.m_Float;
}
sprintf(key, "Sound%d", i+1);
if (g_pServerDE->GetPropGeneric(key, &genProp) == DE_OK)
{
if (genProp.m_String[0])
m_hstrSound[i] = g_pServerDE->CreateString(genProp.m_String);
}
sprintf(key, "WhoPlaysSound%d", i+1);
if (g_pServerDE->GetPropGeneric(key, &genProp) == DE_OK)
{
if (genProp.m_String[0])
m_hstrWhoPlaysSound[i] = g_pServerDE->CreateString(genProp.m_String);
}
sprintf(key, "StartSoundTriggerTarget%d", i+1);
if (g_pServerDE->GetPropGeneric(key, &genProp) == DE_OK)
{
if (genProp.m_String[0])
m_hstrTargetName[i] = g_pServerDE->CreateString(genProp.m_String);
}
sprintf(key, "StartSoundTriggerMsg%d", i+1);
if (g_pServerDE->GetPropGeneric(key, &genProp) == DE_OK)
{
if (genProp.m_String[0])
m_hstrMessageName[i] = g_pServerDE->CreateString(genProp.m_String);
}
}
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CinematicTrigger::Update
//
// PURPOSE: Handle Update
//
// ----------------------------------------------------------------------- //
DBOOL CinematicTrigger::Update()
{
if (!g_pServerDE) return DFALSE;
// See if we are playing a sound...
if (m_hCurSound)
{
// If sound is done, stop it and set next update to wait delay...
DBOOL bDone = DFALSE;
DRESULT dRes = g_pServerDE->IsSoundDone(m_hCurSound, &bDone);
if (dRes != DE_OK || bDone)
{
g_pServerDE->KillSound(m_hCurSound);
m_hCurSound = DNULL;
m_nCurMessage++;
if (m_nCurMessage < MAX_CT_MESSAGES)
{
g_pServerDE->SetNextUpdate(m_hObject, m_fDelay[m_nCurMessage] + 0.0001f);
return DTRUE;
}
else
{
return DFALSE;
}
}
}
else
{
// See if we're done...
if (m_nCurMessage >= MAX_CT_MESSAGES || !m_hstrSound[m_nCurMessage])
{
return DFALSE;
}
// Start next sound...
StartSound();
}
g_pServerDE->SetNextUpdate(m_hObject, 0.001f);
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CinematicTrigger::EngineMessageFn
//
// PURPOSE: Handle engine messages
//
// ----------------------------------------------------------------------- //
DDWORD CinematicTrigger::EngineMessageFn(DDWORD messageID, void *pData, float fData)
{
switch(messageID)
{
case MID_UPDATE:
{
if (!Update())
{
g_pServerDE->RemoveObject(m_hObject);
return DFALSE;
}
break;
}
case MID_PRECREATE:
{
if (fData == PRECREATE_WORLDFILE || fData == PRECREATE_STRINGPROP)
{
ReadProp((ObjectCreateStruct*)pData);
}
break;
}
case MID_INITIALUPDATE:
{
if (fData != INITIALUPDATE_SAVEGAME)
{
// Mark this object as savable
DDWORD dwFlags = g_pServerDE->GetObjectUserFlags(m_hObject);
dwFlags |= USRFLG_SAVEABLE;
g_pServerDE->SetObjectUserFlags(m_hObject, dwFlags);
// Wait for a trigger message...
g_pServerDE->SetNextUpdate(m_hObject, 0.0f);
}
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: CinematicTrigger::ObjectMessageFn
//
// PURPOSE: Handle object messages
//
// ----------------------------------------------------------------------- //
DDWORD CinematicTrigger::ObjectMessageFn(HOBJECT hSender, DDWORD messageID, HMESSAGEREAD hRead)
{
switch (messageID)
{
case MID_TRIGGER :
{
// Start updating the object...
g_pServerDE->SetNextUpdate(m_hObject, m_fDelay[0] + 0.0001f);
}
break;
default : break;
}
return B2BaseClass::ObjectMessageFn(hSender, messageID, hRead);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CinematicTrigger::SendMessages
//
// PURPOSE: Sends the CinematicTrigger messages
//
// ----------------------------------------------------------------------- //
void CinematicTrigger::SendMessage()
{
if (m_nCurMessage < MAX_CT_MESSAGES)
{
if (m_hstrTargetName[m_nCurMessage] && m_hstrMessageName[m_nCurMessage])
{
SendTriggerMsgToObjects(this, m_hstrTargetName[m_nCurMessage], m_hstrMessageName[m_nCurMessage]);
}
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CinematicTrigger::StartSound
//
// PURPOSE: Start the appropriate sound
//
// ----------------------------------------------------------------------- //
void CinematicTrigger::StartSound()
{
char *pName;
if (!g_pServerDE || m_nCurMessage >= MAX_CT_MESSAGES) return;
if (m_hCurSound)
{
g_pServerDE->KillSound(m_hCurSound);
m_hCurSound = DNULL;
}
SendMessage();
PlaySoundInfo playSoundInfo;
PLAYSOUNDINFO_INIT(playSoundInfo);
playSoundInfo.m_dwFlags = PLAYSOUND_TIME | PLAYSOUND_GETHANDLE | PLAYSOUND_REVERB;
pName = g_pServerDE->GetStringData(m_hstrWhoPlaysSound[m_nCurMessage]);
if( !pName )
{
playSoundInfo.m_dwFlags |= PLAYSOUND_3D | PLAYSOUND_ATTACHED;
playSoundInfo.m_hObject = m_hObject;
}
else if( stricmp( pName, "player" ) == 0 )
playSoundInfo.m_dwFlags |= PLAYSOUND_LOCAL;
else
{
playSoundInfo.m_dwFlags |= PLAYSOUND_3D | PLAYSOUND_ATTACHED;
playSoundInfo.m_hObject = PlayedBy( pName );
}
char* pSound = g_pServerDE->GetStringData(m_hstrSound[m_nCurMessage]);
if (!pSound) return;
DFLOAT fRadius = 1000.0f;
_mbsncpy((unsigned char*)playSoundInfo.m_szSoundName, (const unsigned char*)pSound, _MAX_PATH);
playSoundInfo.m_nPriority = SOUNDPRIORITY_PLAYER_HIGH;
playSoundInfo.m_fOuterRadius = fRadius;
playSoundInfo.m_fInnerRadius = fRadius * 0.25f;
playSoundInfo.m_nVolume = 100;
g_pServerDE->PlaySound(&playSoundInfo);
m_hCurSound = playSoundInfo.m_hSound;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CinematicTrigger::PlayedBy
//
// PURPOSE: Get the object that plays the sound
//
// ----------------------------------------------------------------------- //
HOBJECT CinematicTrigger::PlayedBy( char *pszName )
{
if (!g_pServerDE || m_nCurMessage >= MAX_CT_MESSAGES) return m_hObject;
if( !pszName )
return m_hObject;
ObjectList* pList = g_pServerDE->FindNamedObjects( pszName );
if (!pList) return m_hObject;
ObjectLink* pLink = pList->m_pFirstLink;
while(pLink)
{
if (pLink)
{
return pLink->m_hObject;
}
pLink = pLink->m_pNext;
}
g_pServerDE->RelinquishList(pList);
return m_hObject;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CinematicTrigger::Save
//
// PURPOSE: Save the object
//
// ----------------------------------------------------------------------- //
void CinematicTrigger::Save(HMESSAGEWRITE hWrite, DDWORD dwSaveFlags)
{
CServerDE* pServerDE = GetServerDE();
if (!pServerDE || !hWrite) return;
pServerDE->WriteToMessageByte(hWrite, m_nCurMessage);
for (int i=0; i < MAX_CT_MESSAGES; i++)
{
pServerDE->WriteToMessageFloat(hWrite, m_fDelay[i]);
pServerDE->WriteToMessageHString(hWrite, m_hstrSound[i]);
pServerDE->WriteToMessageHString(hWrite, m_hstrWhoPlaysSound[i]);
pServerDE->WriteToMessageHString(hWrite, m_hstrTargetName[i]);
pServerDE->WriteToMessageHString(hWrite, m_hstrMessageName[i]);
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CinematicTrigger::Load
//
// PURPOSE: Load the object
//
// ----------------------------------------------------------------------- //
void CinematicTrigger::Load(HMESSAGEREAD hRead, DDWORD dwLoadFlags)
{
CServerDE* pServerDE = GetServerDE();
if (!pServerDE || !hRead) return;
m_nCurMessage = pServerDE->ReadFromMessageByte(hRead);
for (int i=0; i < MAX_CT_MESSAGES; i++)
{
m_fDelay[i] = pServerDE->ReadFromMessageFloat(hRead);
m_hstrSound[i] = pServerDE->ReadFromMessageHString(hRead);
m_hstrWhoPlaysSound[i] = pServerDE->ReadFromMessageHString(hRead);
m_hstrTargetName[i] = pServerDE->ReadFromMessageHString(hRead);
m_hstrMessageName[i] = pServerDE->ReadFromMessageHString(hRead);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -