📄 triplaser.cpp
字号:
//
// ROUTINE: TripLaser::InitialUpdate
//
// PURPOSE: Handle initial Update
//
// ----------------------------------------------------------------------- //
void TripLaser::InitialUpdate()
{
CServerDE* pServerDE = GetServerDE();
if (!pServerDE) return;
// Mark this object as savable
DDWORD dwUsrFlags = pServerDE->GetObjectUserFlags(m_hObject);
dwUsrFlags |= USRFLG_SAVEABLE;
pServerDE->SetObjectUserFlags(m_hObject, dwUsrFlags);
// Scale color values from 0-255 to 0-1;
VEC_DIVSCALAR(m_vColor, m_vColor, 255.0f);
// Create the model
VEC_MULSCALAR(m_vDims, m_vDims, 2.0f);
pServerDE->ScaleObject(m_hObject, &m_vDims);
// Set the color
pServerDE->SetObjectColor(m_hObject, m_vColor.x, m_vColor.y, m_vColor.z, m_fAlpha);
// Compute the endpoints of the laser
DVector vPos, vF, vR, vU, vTmp;
DRotation rRot;
// Use the longest dimension of m_vDims..
pServerDE->GetObjectPos(m_hObject, &vPos);
pServerDE->GetObjectRotation(m_hObject, &rRot);
pServerDE->GetRotationVectors(&rRot, &vU, &vR, &vF);
if (m_vDims.x >= m_vDims.y && m_vDims.x >= m_vDims.z)
{
VEC_MULSCALAR(vTmp, vR, m_vDims.x);
}
else if (m_vDims.y >= m_vDims.x && m_vDims.y >= m_vDims.z)
{
VEC_MULSCALAR(vTmp, vU, m_vDims.y);
}
else if (m_vDims.z >= m_vDims.x && m_vDims.z >= m_vDims.y)
{
VEC_MULSCALAR(vTmp, vF, m_vDims.z);
}
VEC_MULSCALAR(vTmp, vTmp, 0.5f);
VEC_SUB(m_vEndPoints[0], vPos, vTmp);
VEC_ADD(m_vEndPoints[1], vPos, vTmp);
// Make sure the dims have at least some thickness..
vTmp.x = (DFLOAT)fabs(vTmp.x);
vTmp.y = (DFLOAT)fabs(vTmp.y);
vTmp.z = (DFLOAT)fabs(vTmp.z);
if (vTmp.x <= 1.0f) vTmp.x = 1.0f;
if (vTmp.y <= 1.0f) vTmp.y = 1.0f;
if (vTmp.z <= 1.0f) vTmp.z = 1.0f;
pServerDE->SetObjectDims(m_hObject, &vTmp);
// Tell the clients about the TripLaser
if (m_bTriggered)
{
m_dwFlags |= FLAG_VISIBLE | FLAG_TOUCH_NOTIFY | FLAG_NOLIGHT;
// Play the sound, if any
if (m_hstrSound)
m_hSound = PlaySoundFromObject(m_hObject,
pServerDE->GetStringData(m_hstrSound),
400, SOUNDPRIORITY_MISC_LOW,
DTRUE, DTRUE, DTRUE);
}
pServerDE->SetObjectFlags(m_hObject, m_dwFlags);
pServerDE->SetNextUpdate(m_hObject, 0.0f);
}
// --------------------------------------------------------------------------- //
//
// ROUTINE: TripLaser::TriggerMsg()
//
// PURPOSE: Handler for TripLaser trigger messages.
//
// --------------------------------------------------------------------------- //
void TripLaser::TriggerMsg(HOBJECT hSender, HSTRING hMsg)
{
CServerDE* pServerDE = GetServerDE();
HSTRING hstr;
hstr = pServerDE->CreateString(g_szTriggerOn);
if (pServerDE->CompareStringsUpper(hMsg, hstr))
{
m_bTriggered = DTRUE;
m_dwFlags = FLAG_TOUCH_NOTIFY | FLAG_VISIBLE | FLAG_NOLIGHT;
if (m_hstrSound && !m_hSound)
m_hSound = PlaySoundFromObject(m_hObject,
pServerDE->GetStringData(m_hstrSound),
400, SOUNDPRIORITY_MISC_LOW,
DTRUE, DTRUE, DTRUE);
}
pServerDE->FreeString(hstr);
hstr = pServerDE->CreateString(g_szTriggerOff);
if (pServerDE->CompareStringsUpper(hMsg, hstr))
{
m_bTriggered = DFALSE;
m_dwFlags = 0;
if (m_hSound)
{
pServerDE->KillSound(m_hSound);
m_hSound = DNULL;
}
// Set update so it'll flash a little
DFLOAT fNextUpdate = pServerDE->Random(0.25f, 0.5f);
pServerDE->SetNextUpdate(m_hObject, fNextUpdate);
}
pServerDE->FreeString(hstr);
// Kill trigger message
hstr = pServerDE->CreateString(g_szTriggerKill);
if (pServerDE->CompareStringsUpper(hMsg, hstr))
{
m_bTriggered = DFALSE;
m_dwFlags = 0;
if (m_hSound)
{
pServerDE->KillSound(m_hSound);
m_hSound = DNULL;
}
// Set update so it'll flash a little
DFLOAT fNextUpdate = pServerDE->Random(0.25f, 0.5f);
pServerDE->SetNextUpdate(m_hObject, fNextUpdate);
m_bRemove = DTRUE;
}
pServerDE->FreeString(hstr);
pServerDE->SetObjectFlags(m_hObject, m_dwFlags);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: TripLaser::HandleTouch()
//
// PURPOSE: Handle touch notify message
//
// ----------------------------------------------------------------------- //
void TripLaser::HandleTouch(HOBJECT hObj)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return;
// Apply damage 10 times a second.
DFLOAT fTime = pServerDE->GetTime();
if (fTime <= m_fDamageTime)
return;
m_fDamageTime = fTime + DAMAGE_UPDATE_DELTA;
// Something's touching the bounding box, so cast a line
// between the endpoints and see if the laser hits it.
IntersectQuery iq;
IntersectInfo ii;
VEC_COPY(iq.m_From, m_vEndPoints[0]); // Get start point at the last known position.
VEC_COPY(iq.m_To, m_vEndPoints[1]); // Get start point at the last known position.
iq.m_Flags = INTERSECT_OBJECTS | IGNORE_NONSOLID | INTERSECT_HPOLY;
iq.m_FilterFn = NULL;
iq.m_pUserData = NULL;
// Hit something!
if (pServerDE->IntersectSegment(&iq, &ii))
{
if (ii.m_hObject == hObj) // hit it!
{
DVector vDir;
VEC_SUB(vDir, m_vEndPoints[1], m_vEndPoints[0]);
// Send damage message to object...
DamageObject(m_hObject, this, hObj, m_fDamage*DAMAGE_UPDATE_DELTA, vDir, ii.m_Point, DAMAGE_TYPE_NORMAL);
if (m_hstrTouchSound)
PlaySoundFromObject(m_hObject,
pServerDE->GetStringData(m_hstrTouchSound),
800, SOUNDPRIORITY_MISC_HIGH);
}
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: TripLaser::Save
//
// PURPOSE: Save the object
//
// ----------------------------------------------------------------------- //
void TripLaser::Save(HMESSAGEWRITE hWrite, DDWORD dwSaveFlags)
{
CServerDE* pServerDE = GetServerDE();
if (!pServerDE || !hWrite) return;
DFLOAT fTime = pServerDE->GetTime();
pServerDE->WriteToMessageVector(hWrite, &m_vDims);
pServerDE->WriteToMessageVector(hWrite, &m_vColor);
pServerDE->WriteToMessageFloat(hWrite, m_fAlpha);
pServerDE->WriteToMessageFloat(hWrite, m_fDamage);
pServerDE->WriteToMessageFloat(hWrite, m_fDamageTime - fTime);
pServerDE->WriteToMessageHString(hWrite, m_hstrTriggerTarget);
pServerDE->WriteToMessageHString(hWrite, m_hstrTriggerMessage);
pServerDE->WriteToMessageHString(hWrite, m_hstrSound);
pServerDE->WriteToMessageHString(hWrite, m_hstrTouchSound);
pServerDE->WriteToMessageVector(hWrite, &m_vEndPoints[0]);
pServerDE->WriteToMessageVector(hWrite, &m_vEndPoints[1]);
pServerDE->WriteToMessageDWord(hWrite, m_dwFlags);
pServerDE->WriteToMessageByte(hWrite, m_bTriggered);
pServerDE->WriteToMessageByte(hWrite, m_bRemove);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: TripLaser::Load
//
// PURPOSE: Load the object
//
// ----------------------------------------------------------------------- //
void TripLaser::Load(HMESSAGEREAD hRead, DDWORD dwLoadFlags)
{
CServerDE* pServerDE = GetServerDE();
if (!pServerDE || !hRead) return;
DFLOAT fTime = pServerDE->GetTime();
pServerDE->ReadFromMessageVector(hRead, &m_vDims);
pServerDE->ReadFromMessageVector(hRead, &m_vColor);
m_fAlpha = pServerDE->ReadFromMessageFloat(hRead);
m_fDamage = pServerDE->ReadFromMessageFloat(hRead);
m_fDamageTime = pServerDE->ReadFromMessageFloat(hRead) + fTime;
m_hstrTriggerTarget = pServerDE->ReadFromMessageHString(hRead);
m_hstrTriggerMessage= pServerDE->ReadFromMessageHString(hRead);
m_hstrSound = pServerDE->ReadFromMessageHString(hRead);
m_hstrTouchSound = pServerDE->ReadFromMessageHString(hRead);
pServerDE->ReadFromMessageVector(hRead, &m_vEndPoints[0]);
pServerDE->ReadFromMessageVector(hRead, &m_vEndPoints[1]);
m_dwFlags = pServerDE->ReadFromMessageDWord(hRead);
m_bTriggered = pServerDE->ReadFromMessageByte(hRead);
m_bRemove = pServerDE->ReadFromMessageByte(hRead);
// Tell the clients about the TripLaser
if (m_bTriggered)
{
if( m_hSound )
{
pServerDE->KillSound( m_hSound );
m_hSound = DNULL;
}
// Play the sound, if any
if( m_hstrSound && m_hObject )
m_hSound = PlaySoundFromObject(m_hObject,
pServerDE->GetStringData(m_hstrSound),
400, SOUNDPRIORITY_MISC_LOW,
DTRUE, DTRUE, DTRUE);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -