📄 door.cpp
字号:
// PURPOSE: Trigger function to only close a door (useful for stay-open-
// forever types.
//
// --------------------------------------------------------------------------- //
void Door::TriggerClose()
{
if (m_dwDoorState == DOORSTATE_OPEN || m_dwDoorState == DOORSTATE_OPENING)
{
SetClosing();
}
}
// --------------------------------------------------------------------------- //
//
// ROUTINE: Door::InitialUpdate()
//
// PURPOSE: Initializes door data.
//
// --------------------------------------------------------------------------- //
DBOOL Door::InitialUpdate(int nInfo)
{
CServerDE* pServerDE = GetServerDE();
if (nInfo == INITIALUPDATE_SAVEGAME)
return DTRUE;
if (m_dwTriggerFlags & DTF_SELFTRIGGER)
{
SpawnTrigger();
}
SetClosed(DFALSE);
// Calculate open & close positions
DVector vt, pos;
VEC_NORM(m_vMoveDir)
// Current position is the closed position
pServerDE->GetObjectPos(m_hObject, &pos);
VEC_COPY(m_vClosedPos, pos);
// Determine the open position
VEC_MULSCALAR(vt, m_vMoveDir, m_fMoveDist);
VEC_ADD(m_vOpenPos, m_vClosedPos, vt);
// If start open, simply swap open & closed positions
if (m_dwTriggerFlags & DTF_STARTOPEN)
{
VEC_COPY(vt, m_vOpenPos);
VEC_COPY(m_vOpenPos, m_vClosedPos);
VEC_COPY(m_vClosedPos, vt);
VEC_MULSCALAR(m_vMoveDir, m_vMoveDir, -1.0f);
pServerDE->MoveObject(m_hObject, &m_vClosedPos);
}
pServerDE->SetBlockingPriority(m_hObject, DOOR_DEFAULT_BLOCKING_PRIORITY);
// Initially closed
SetClosed(DFALSE);
// Set the portal state if there is one
// SetPortalState(DFALSE);
pServerDE->SetNextUpdate(m_hObject, (DFLOAT).01);
// Mark this object as savable
DDWORD dwFlags = pServerDE->GetObjectUserFlags(m_hObject);
dwFlags |= USRFLG_SAVEABLE;
pServerDE->SetObjectUserFlags(m_hObject, dwFlags);
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: Door::SpawnTrigger()
//
// PURPOSE: Spawn a trigger object
//
// ----------------------------------------------------------------------- //
void Door::SpawnTrigger()
{
CServerDE* pServerDE = GetServerDE();
if (!pServerDE || m_hTriggerObj) return;
DVector vPos;
pServerDE->GetObjectPos(m_hObject, &vPos);
ObjectCreateStruct theStruct;
INIT_OBJECTCREATESTRUCT(theStruct);
VEC_COPY(theStruct.m_Pos, vPos);
HCLASS hClass = pServerDE->GetClass("Trigger");
Trigger* pTriggerObj = (Trigger*)pServerDE->CreateObject(hClass, &theStruct);
if (pTriggerObj)
{
DVector vDims;
if (m_vTriggerDims.x == 0.0f && m_vTriggerDims.y == 0.0f && m_vTriggerDims.z == 0.0f)
{
pServerDE->GetObjectDims(m_hObject, &vDims);
vDims.x += 1.0f;
vDims.y += 1.0f;
vDims.z += 1.0f;
}
else
{
VEC_COPY(vDims, m_vTriggerDims);
}
// pTriggerObj->SetActive(DTRUE);
// pTriggerObj->SetTargetName(0, pServerDE->GetObjectName(m_hObject));
// pTriggerObj->SetMessageName(0, g_szTrigger);
pServerDE->SetObjectDims(pTriggerObj->m_hObject, &vDims);
m_hTriggerObj = pTriggerObj->m_hObject;
// New: Set up trigger properties
pTriggerObj->Setup(DTRUE,
pServerDE->GetObjectName(m_hObject),
g_szTrigger,
m_bTrigTouchActivate,
m_bTrigPlayerActivate,
m_bTrigAIActivate,
m_bTrigObjectActivate,
m_bTrigTriggerRelayActivate,
m_bTrigNamedObjectActivate,
m_hstrTrigActivationObjectName,
m_bTrigLocked,
DNULL,
m_hstrTrigLockedSound,
DNULL,
m_hstrTrigUnlockedSound,
m_hstrTrigKeyName);
}
}
// --------------------------------------------------------------------------- //
//
// ROUTINE: Door::Update()
//
// PURPOSE: Door update function, updates the current state.
//
// --------------------------------------------------------------------------- //
DBOOL Door::Update(DVector *pMovement)
{
CServerDE* pServerDE = GetServerDE();
pServerDE->SetNextUpdate(m_hObject, (DFLOAT).01);
switch (m_dwDoorState)
{
case DOORSTATE_OPEN: Open(); break;
case DOORSTATE_OPENING: Opening(); break;
case DOORSTATE_CLOSED: Closed(); break;
case DOORSTATE_CLOSING: Closing(); break;
}
// Reset blocked state
m_bDoorBlocked = DFALSE;
return DTRUE;
}
// --------------------------------------------------------------------------- //
//
// ROUTINE: Door::SetOpen()
//
// PURPOSE: Sets the door open state
//
// --------------------------------------------------------------------------- //
void Door::SetOpen(DBOOL bPlaySound)
{
CServerDE* pServerDE = GetServerDE();
if (bPlaySound)
{
StartSound(m_hstrOpenStopSound, DFALSE);
}
m_dwDoorState = DOORSTATE_OPEN;
if (m_dwTriggerFlags & DTF_TRIGGERCLOSED)
pServerDE->SetNextUpdate(m_hObject, (DFLOAT)0);
else if (m_dwTriggerFlags & DTF_REMAINSOPEN)
pServerDE->SetNextUpdate(m_hObject, (DFLOAT)0);
else
m_fDoorOpenTime = m_fWaitTime;
}
// --------------------------------------------------------------------------- //
//
// ROUTINE: Door::Open()
//
// PURPOSE: Handles the door open state
//
// --------------------------------------------------------------------------- //
void Door::Open()
{
CServerDE* pServerDE = GetServerDE();
// Changed to count down instead of relying on GetTime GK 4/17/98
DFLOAT fTime = pServerDE->GetFrameTime();
m_fDoorOpenTime -= fTime;
if (m_fDoorOpenTime <= 0)
{
m_fDoorOpenTime = 0;
SetClosing();
}
}
// --------------------------------------------------------------------------- //
//
// ROUTINE: Door::SetOpening()
//
// PURPOSE: Sets the door opening state
//
// --------------------------------------------------------------------------- //
void Door::SetOpening()
{
CServerDE* pServerDE = GetServerDE();
if (m_hTriggerObj)
{
Trigger* pTriggerObj = (Trigger*)pServerDE->HandleToObject(m_hTriggerObj);
if (pTriggerObj)
{
pTriggerObj->SetActive(DFALSE);
}
}
pServerDE->SetNextUpdate(m_hObject, m_fOpenDelay);
m_bStartedMoving = DFALSE;
m_dwDoorState = DOORSTATE_OPENING;
}
// --------------------------------------------------------------------------- //
//
// ROUTINE: Door::Opening()
//
// PURPOSE: Handles the door opening state
//
// --------------------------------------------------------------------------- //
void Door::Opening()
{
CServerDE* pServerDE = GetServerDE();
DFLOAT distTo, moveDist;
DVector vDir, pos;
if (!m_bStartedMoving)
{
m_bStartedMoving = DTRUE;
StartSound(m_hstrOpenBusySound, DTRUE);
SetPortalState(DTRUE);
}
pServerDE->GetObjectPos(m_hObject, &pos);
VEC_SUB(vDir, m_vOpenPos, pos)
distTo = (DFLOAT)VEC_MAG(vDir);
VEC_NORM(vDir)
DFLOAT fPercent = 1 - distTo / m_fMoveDist;
DFLOAT fSpeed = GetWaveValue(m_fSpeed, fPercent, m_dwWaveform);
moveDist = fSpeed * pServerDE->GetFrameTime();
if (moveDist > distTo)
{
pServerDE->MoveObject(m_hObject, &m_vOpenPos);
SetOpen();
}
else
{
VEC_MULSCALAR(vDir, vDir, moveDist)
VEC_ADD(pos, pos, vDir)
pServerDE->MoveObject(m_hObject, &pos);
}
}
// --------------------------------------------------------------------------- //
//
// ROUTINE: Door::SetClosed()
//
// PURPOSE: Sets the door closed state
//
// --------------------------------------------------------------------------- //
void Door::SetClosed(DBOOL bPlaySound)
{
CServerDE* pServerDE = GetServerDE();
if (!pServerDE) return;
if (bPlaySound)
{
StartSound(m_hstrCloseStopSound, DFALSE);
}
pServerDE->SetNextUpdate(m_hObject, (DFLOAT)0);
m_dwDoorState = DOORSTATE_CLOSED;
if (m_dwTriggerFlags & DTF_SELFTRIGGER)
{
Trigger* pTriggerObj = (Trigger*)pServerDE->HandleToObject(m_hTriggerObj);
if (pTriggerObj)
{
pTriggerObj->SetActive(DTRUE);
}
}
SetPortalState(DFALSE);
}
// --------------------------------------------------------------------------- //
//
// ROUTINE: Door::Closed()
//
// PURPOSE: Sets the door closed state
//
// --------------------------------------------------------------------------- //
void Door::Closed()
{
}
// --------------------------------------------------------------------------- //
//
// ROUTINE: Door::SetClosing()
//
// PURPOSE: Sets the door closing state
//
// --------------------------------------------------------------------------- //
void Door::SetClosing()
{
CServerDE* pServerDE = GetServerDE();
pServerDE->SetNextUpdate(m_hObject, (DFLOAT).01);
m_dwDoorState = DOORSTATE_CLOSING;
StartSound(m_hstrCloseBusySound, DTRUE);
}
// --------------------------------------------------------------------------- //
//
// ROUTINE: Door::Closing()
//
// PURPOSE: Handles the door closing state
//
// --------------------------------------------------------------------------- //
void Door::Closing()
{
CServerDE* pServerDE = GetServerDE();
DFLOAT distTo, moveDist;
DVector vDir, pos;
pServerDE->GetObjectPos(m_hObject, &pos);
VEC_SUB(vDir, m_vClosedPos, pos)
distTo = (DFLOAT)VEC_MAG(vDir);
VEC_NORM(vDir)
DFLOAT fPercent = 1 - distTo / m_fMoveDist;
DFLOAT fSpeed = GetWaveValue(m_fClosingSpeed, fPercent, m_dwWaveform);
moveDist = fSpeed * pServerDE->GetFrameTime();
if (moveDist > distTo)
{
pServerDE->MoveObject(m_hObject, &m_vClosedPos);
SetClosed();
}
else
{
VEC_MULSCALAR(vDir, vDir, moveDist)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -