📄 keyframer.cpp
字号:
// ----------------------------------------------------------------------- //
//
// MODULE : Keyframer.cpp
//
// PURPOSE : Keyframer implementation
//
// CREATED : 10/7/97
//
// ----------------------------------------------------------------------- //
#include "KeyFramer.h"
#include "cpp_server_de.h"
#include "ObjectUtilities.h"
#include "stdio.h"
#include "generic_msg_de.h"
#include "trigger.h"
#include "CameraObj.h"
#include "BloodServerShell.h"
#include "ClientServerShared.h"
#include <mbstring.h>
#include "SoundTypes.h"
BEGIN_CLASS(KeyFramer)
ADD_STRINGPROP(ObjectName, "")
ADD_STRINGPROP(BaseKeyName, "")
ADD_BOOLPROP(StartActive, DFALSE)
ADD_BOOLPROP(Looping, DFALSE)
END_CLASS_DEFAULT(KeyFramer, B2BaseClass, NULL, NULL)
// ----------------------------------------------------------------------- //
//
// ROUTINE: KeyFramer::KeyFramer()
//
// PURPOSE: Initialize object
//
// ----------------------------------------------------------------------- //
KeyFramer::KeyFramer() : B2BaseClass(OT_NORMAL)
{
m_hstrObjectName = NULL;
m_hstrBaseKeyName = NULL;
m_bStartActive = DFALSE;
m_bLooping = DFALSE;
m_bActive = DFALSE;
m_pObjectList = NULL;
m_pOffsets.SetMemCopyable(1);
m_pOffsets.SetGrowBy(3);
m_pRotations.SetMemCopyable(1);
m_pRotations.SetGrowBy(3);
m_pKeys = NULL;
m_pCurKey = NULL;
m_pPosition1 = NULL;
m_pPosition2 = NULL;
m_nNumKeys = 0;
m_fCurTime = 0.0f;
m_bFirstUpdate = DTRUE;
m_hsndKeySound = DNULL;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: KeyFramer::~KeyFramer()
//
// PURPOSE: Deallocate object
//
// ----------------------------------------------------------------------- //
KeyFramer::~KeyFramer()
{
CServerDE* pServerDE = GetServerDE();
if (pServerDE)
{
pServerDE->FreeString (m_hstrObjectName);
pServerDE->FreeString (m_hstrBaseKeyName);
if (m_pObjectList)
{
pServerDE->RelinquishList (m_pObjectList);
}
}
while (m_pKeys)
{
KEYNODE* pNext = m_pKeys->pNext;
delete m_pKeys;
m_pKeys = pNext;
}
if (m_hsndKeySound)
{
pServerDE->KillSound(m_hsndKeySound);
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: KeyFramer::GoActive
//
// PURPOSE: Start the KeyFramer going!
//
// ----------------------------------------------------------------------- //
void KeyFramer::GoActive()
{
CServerDE* pServerDE = GetServerDE();
if (!pServerDE || m_bActive || !m_pKeys) return;
m_bStartActive = DTRUE;
// Go active
m_bActive = DTRUE;
m_fCurTime = 0.0f;
m_pCurKey = m_pKeys;
pServerDE->SetNextUpdate(m_hObject, 0.001f);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: KeyFramer::CreateKeyList
//
// PURPOSE: Create our list of keys.
//
// ----------------------------------------------------------------------- //
DBOOL KeyFramer::CreateKeyList()
{
CServerDE* pServerDE = GetServerDE();
if (!pServerDE) return DFALSE;
// Create the list of keys...
int nNum = 0;
DFLOAT fTime = 0.0f;
KEYNODE* pNode = NULL;
while (1)
{
// Create the keyname string...
char strKey[128]; memset (strKey, 0, 128);
char strNum[18]; memset (strNum, 0, 18);
_itoa (nNum, strNum, 10);
char *pszBaseKeyName = pServerDE->GetStringData (m_hstrBaseKeyName);
if( pszBaseKeyName )
_mbscpy ((unsigned char*)strKey, (const unsigned char*)pszBaseKeyName);
else
strKey[0] = 0;
_mbscat ((unsigned char*)strKey, (const unsigned char*)strNum);
// Find the first key with that name...
ObjectList* pTempKeyList = pServerDE->FindNamedObjects (strKey);
ObjectLink* pLink = pTempKeyList->m_pFirstLink;
DBOOL bFoundKey = DFALSE;
while (pLink && !bFoundKey)
{
if (pServerDE->IsKindOf (pServerDE->GetObjectClass (pLink->m_hObject), pServerDE->GetClass ("Key")))
{
// Add this key to the list...
if (!m_pKeys)
{
m_pKeys = new KEYNODE;
pNode = m_pKeys;
}
else
{
pNode->pNext = new KEYNODE;
pNode->pNext->pPrev = pNode;
pNode = pNode->pNext;
}
// Copy the key...
pNode->keyData.Copy((Key*)pServerDE->HandleToObject(pLink->m_hObject));
fTime += pNode->keyData.m_fTimeStamp;
pNode->keyData.m_fRealTime = fTime;
// Remove the key from the world...No longer needed...
pServerDE->RemoveObject(pLink->m_hObject);
bFoundKey = DTRUE;
m_nNumKeys++;
}
pLink = pLink->m_pNext;
}
pServerDE->RelinquishList (pTempKeyList);
// If we didn't find a key, we're done looking...
if (!pLink && !bFoundKey)
{
break;
}
// Increment the counter...
nNum++;
}
// If we didn't find any keys, return...
if (!m_pKeys)
{
return DFALSE;
}
// For each object we're controlling, save it's offset from the first key...
KEYNODE* pFirstPosKey = GetNextPositionKey(m_pKeys);
if (pFirstPosKey)
{
// Get the first position key's location
DVector pos;
DRotation rot;
VEC_COPY(pos, pFirstPosKey->keyData.m_vPos);
ROT_COPY(rot, pFirstPosKey->keyData.m_rRot);
long i = 0;
ObjectLink* pLink = m_pObjectList->m_pFirstLink;
while (pLink)
{
DVector objpos;
pServerDE->GetObjectPos(pLink->m_hObject, &objpos);
VEC_SUB(m_pOffsets[i], objpos, pos);
DRotation objrot;
pServerDE->GetObjectRotation(pLink->m_hObject, &objrot);
VEC_SUB(m_pRotations[i].m_Vec, objrot.m_Vec, rot.m_Vec);
m_pRotations[i].m_Spin = objrot.m_Spin - rot.m_Spin;
i++;
pLink = pLink->m_pNext;
}
}
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: KeyFramer::BuildObjectList
//
// PURPOSE: Builds the list of objects to control
//
// ----------------------------------------------------------------------- //
DBOOL KeyFramer::BuildObjectList()
{
CServerDE* pServerDE = GetServerDE();
if (!pServerDE || !m_hstrObjectName) return DFALSE;
if (!m_pObjectList)
{
// Find the objects...
m_pObjectList = pServerDE->FindNamedObjects(pServerDE->GetStringData(m_hstrObjectName));
if (m_pObjectList->m_nInList)
{
// Create links to all these objects so we know if/when they
// get removed...
ObjectLink* pLink = m_pObjectList->m_pFirstLink;
while (pLink)
{
pServerDE->CreateInterObjectLink(m_hObject, pLink->m_hObject);
pLink = pLink->m_pNext;
}
}
}
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: KeyFramer::GetNextPositionKey
//
// PURPOSE: Returns the next key with position type
//
// ----------------------------------------------------------------------- //
KEYNODE* KeyFramer::GetNextPositionKey(KEYNODE* pNode)
{
if (!pNode) return NULL;
while (pNode)
{
if (pNode->keyData.m_nKeyType & POSITION_KEY)
{
return pNode;
}
pNode = pNode->pNext;
}
return NULL;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: KeyFramer::ProcessKey
//
// PURPOSE: Processes the given key
//
// ----------------------------------------------------------------------- //
void KeyFramer::ProcessKey (KEYNODE* pNode)
{
CServerDE* pServerDE = GetServerDE();
if (!pServerDE) return;
if (pNode->keyData.m_nKeyType & POSITION_KEY)
{
m_pPosition1 = pNode;
m_pPosition2 = GetNextPositionKey(pNode->pNext);
}
if (pNode->keyData.m_nKeyType & SOUND_KEY)
{
ObjectLink* pLink = m_pObjectList->m_pFirstLink;
while (pLink && pLink->m_hObject)
{
// kill current sound
if (m_hsndKeySound)
{
pServerDE->KillSound(m_hsndKeySound);
}
m_hsndKeySound = PlaySoundFromObject(pLink->m_hObject, pServerDE->GetStringData(pNode->keyData.m_hstrSoundName), pNode->keyData.m_fSoundRadius, SOUNDPRIORITY_MISC_MEDIUM, pNode->keyData.m_bLoopSound, DTRUE, DTRUE );
pLink = pLink->m_pNext;
}
}
if (pNode->keyData.m_nKeyType & MESSAGE_KEY)
{
SendTriggerMsgToObjects(this, pNode->keyData.m_hstrMessageTarget, pNode->keyData.m_hstrMessageName);
}
if (pNode->keyData.m_nKeyType & BPRINT_KEY)
{
pServerDE->BPrint(pServerDE->GetStringData(pNode->keyData.m_hstrBPrintMessage));
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: KeyFramer::EngineMessageFn
//
// PURPOSE: Handle engine messages
//
// ----------------------------------------------------------------------- //
DDWORD KeyFramer::EngineMessageFn(DDWORD messageID, void *pData, DFLOAT fData)
{
switch(messageID)
{
case MID_UPDATE:
{
Update((DVector *)pData);
break;
}
case MID_PRECREATE:
{
if (fData == PRECREATE_WORLDFILE)
{
ReadProp((ObjectCreateStruct *)pData);
}
break;
}
case MID_INITIALUPDATE:
{
if (fData != INITIALUPDATE_SAVEGAME)
{
InitialUpdate((DVector *)pData);
}
break;
}
case MID_LINKBROKEN :
{
HOBJECT hLink = (HOBJECT)pData;
if (m_pObjectList && hLink)
{
ObjectLink* pLink = m_pObjectList->m_pFirstLink;
while (pLink)
{
if (pLink->m_hObject == hLink)
{
g_pServerDE->RemoveObjectFromList(m_pObjectList, pLink->m_hObject);
break;
}
pLink = pLink->m_pNext;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -