📄 objectutilities.cpp
字号:
// ----------------------------------------------------------------------- //
//
// MODULE : Blood2ObjectUtilities.cpp
//
// PURPOSE : Utility functions
//
// CREATED : 2/4/98
//
// ----------------------------------------------------------------------- //
#include <stdlib.h>
#include <stdio.h>
#include "ObjectUtilities.h"
#include "cpp_server_de.h"
#include "LightFX.h"
#include "AI_Mgr.h"
#include "destructablebrush.h"
#include "destructablemodel.h"
//-------------------------------------------------------------------------------------------
// PlaySoundFromObject
//
// Plays sound attached to object.
// Arguments:
// hObject - Handle to object
// pSoundName - path of sound file.
// fRadius - max radius of sound.
// bLoop - Loop the sound (default: false)
// bHandle - Return handle to sound (default: false)
// bTime - Have server keep track of time (default: false)
// nVolume - Volume 0-100
// bStream - Stream the sound file.
// bInstant - Play sound local to client specified in hObject, but from a position for all other clients.
// Return:
// Handle to sound, if bHandle was set to TRUE.
//-------------------------------------------------------------------------------------------
HSOUNDDE PlaySoundFromObject( HOBJECT hObject, char *pSoundName, DFLOAT fRadius,
DBYTE nSoundPriority, DBOOL bLoop, DBOOL bHandle, DBOOL bTime, DBYTE nVolume,
DBOOL bStream, DBOOL bInstant )
{
if (!pSoundName) return DNULL;
PlaySoundInfo playSoundInfo;
PLAYSOUNDINFO_INIT( playSoundInfo );
playSoundInfo.m_dwFlags = PLAYSOUND_3D | PLAYSOUND_REVERB;
// If instant, then get play the sound at the object's position, but don't attach it to the object. This
// is a big optimization. The clientlocal flag makes the sound play in the head of the hObject if it's
// a client.
if( bInstant )
{
g_pServerDE->GetObjectPos( hObject, &playSoundInfo.m_vPosition );
playSoundInfo.m_dwFlags |= PLAYSOUND_CLIENTLOCAL;
}
else
playSoundInfo.m_dwFlags |= PLAYSOUND_ATTACHED;
if( bLoop )
playSoundInfo.m_dwFlags |= PLAYSOUND_LOOP;
if( bHandle )
playSoundInfo.m_dwFlags |= PLAYSOUND_GETHANDLE;
if ( bStream )
playSoundInfo.m_dwFlags |= PLAYSOUND_FILESTREAM;
if( bTime )
playSoundInfo.m_dwFlags |= PLAYSOUND_TIME;
if ( nVolume < 100)
playSoundInfo.m_dwFlags |= PLAYSOUND_CTRL_VOL;
_mbsncpy((unsigned char*)playSoundInfo.m_szSoundName, (const unsigned char*)pSoundName, _MAX_PATH );
playSoundInfo.m_hObject = hObject;
playSoundInfo.m_nPriority = nSoundPriority;
playSoundInfo.m_fOuterRadius = fRadius;
playSoundInfo.m_fInnerRadius = fRadius * 0.1f;
playSoundInfo.m_nVolume = nVolume;
g_pServerDE->PlaySound( &playSoundInfo );
return playSoundInfo.m_hSound;
}
//-------------------------------------------------------------------------------------------
// PlaySoundFromPos
//
// Plays sound at a position
// Arguments:
// vPos - position of sound
// pSoundName - path of sound file.
// fRadius - max radius of sound.
// bLoop - Loop the sound (default: false)
// bHandle - Return handle to sound (default: false)
// bTime - Have server keep track of time (default: false)
// Return:
// Handle to sound, if bHandle was set to TRUE.
//-------------------------------------------------------------------------------------------
HSOUNDDE PlaySoundFromPos( DVector *vPos, char *pSoundName, DFLOAT fRadius,
DBYTE nSoundPriority, DBOOL bLoop, DBOOL bHandle, DBOOL bTime, DBYTE nVolume,
DBOOL bStream )
{
PlaySoundInfo playSoundInfo;
PLAYSOUNDINFO_INIT( playSoundInfo );
playSoundInfo.m_dwFlags = PLAYSOUND_3D | PLAYSOUND_REVERB;
if( bLoop )
playSoundInfo.m_dwFlags |= PLAYSOUND_LOOP;
if( bHandle )
playSoundInfo.m_dwFlags |= PLAYSOUND_GETHANDLE;
if( bTime )
playSoundInfo.m_dwFlags |= PLAYSOUND_TIME;
if ( bStream )
playSoundInfo.m_dwFlags |= PLAYSOUND_FILESTREAM;
if ( nVolume < 100)
playSoundInfo.m_dwFlags |= PLAYSOUND_CTRL_VOL;
_mbsncpy((unsigned char*)playSoundInfo.m_szSoundName, (const unsigned char*)pSoundName, _MAX_PATH );
VEC_COPY( playSoundInfo.m_vPosition, *vPos );
playSoundInfo.m_nPriority = nSoundPriority;
playSoundInfo.m_fOuterRadius = fRadius;
playSoundInfo.m_fInnerRadius = fRadius * 0.1f;
playSoundInfo.m_nVolume = nVolume;
g_pServerDE->PlaySound( &playSoundInfo );
return playSoundInfo.m_hSound;
}
//-------------------------------------------------------------------------------------------
// PlaySoundLocal
//
// Plays a local sound
// Arguments:
// pSoundName - path of sound file.
// nSoundPriority - priority
// bLoop - Loop the sound
// bHandle - Return handle to sound
// bStream - use file streaming
// nVolume - volume to play the sound (0-100)
// Return:
// Handle to sound, if bHandle was set to TRUE.
//-------------------------------------------------------------------------------------------
HSOUNDDE PlaySoundLocal(char *pSoundName, DBYTE nSoundPriority, DBOOL bLoop, DBOOL bHandle,
DBOOL bStream, DBYTE nVolume)
{
PlaySoundInfo playSoundInfo;
PLAYSOUNDINFO_INIT( playSoundInfo );
playSoundInfo.m_dwFlags = PLAYSOUND_LOCAL;
if ( bLoop )
playSoundInfo.m_dwFlags |= PLAYSOUND_LOOP;
if ( bHandle )
playSoundInfo.m_dwFlags |= PLAYSOUND_GETHANDLE;
if ( bStream )
playSoundInfo.m_dwFlags |= PLAYSOUND_FILESTREAM;
if ( nVolume < 100 )
playSoundInfo.m_dwFlags |= PLAYSOUND_CTRL_VOL;
_mbsncpy((unsigned char*)playSoundInfo.m_szSoundName, (const unsigned char*)pSoundName, _MAX_PATH );
playSoundInfo.m_nPriority = nSoundPriority;
playSoundInfo.m_nVolume = nVolume;
g_pServerDE->PlaySound( &playSoundInfo );
return playSoundInfo.m_hSound;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CreateScorchMark()
//
// PURPOSE: Create a dynamic light that simulates scorch mark
//
// ----------------------------------------------------------------------- //
void CreateScorchMark(DVector *pvPos, DFLOAT fMinLightRadius, DFLOAT fMaxLightRadius,
DFLOAT fRampUpTime, DFLOAT fRampDownTime, DFLOAT fRadiusMinTime,
DFLOAT fRadiusMaxTime, DFLOAT fRed, DFLOAT fGreen, DFLOAT fBlue)
{
if (!g_pServerDE || !pvPos) return;
// Create the outer scorched area
ObjectCreateStruct ocStruct;
INIT_OBJECTCREATESTRUCT(ocStruct);
VEC_COPY(ocStruct.m_Pos, *pvPos);
ocStruct.m_Flags = FLAG_VISIBLE | FLAG_ONLYLIGHTWORLD;
HCLASS hClass = g_pServerDE->GetClass("LightFX");
if (!hClass) return;
LightFX* pMark = (LightFX*)g_pServerDE->CreateObject(hClass, &ocStruct);
if (!pMark) return;
// Set light values...
VEC_SET(pMark->m_vColor1, fRed, fGreen, fBlue);
pMark->m_nNumRadiusCycles = 1;
pMark->m_fRadiusMin = fMinLightRadius;
pMark->m_fRadiusMax = fMaxLightRadius;
pMark->m_fRadiusMinTime = fRadiusMinTime;
pMark->m_fRadiusMaxTime = fRadiusMaxTime;
pMark->m_fRadiusRampUpTime = fRampUpTime;
pMark->m_fRadiusRampDownTime = fRampDownTime;
pMark->m_fLifeTime = (pMark->m_fRadiusMinTime +
pMark->m_fRadiusMaxTime +
pMark->m_fRadiusRampUpTime +
pMark->m_fRadiusRampDownTime);
pMark->Init();
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: GetSurfaceType
//
// PURPOSE: Determines the surface type of an object
//
// ----------------------------------------------------------------------- //
SurfaceType GetSurfaceType(HOBJECT hObject, HPOLY hPoly)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE || !hObject) return SURFTYPE_UNKNOWN;
SurfaceType eType = SURFTYPE_UNKNOWN;
// First see if we hit the world
if (pServerDE->GetWorldObject() == hObject)
{
DDWORD dwFlags;
if (hPoly && pServerDE->GetPolyTextureFlags(hPoly, &dwFlags) == DE_OK)
{
eType = (SurfaceType)dwFlags;
}
}
// Now check for object types
else
{
// Upper byte of UserFlags should be a surface type
eType = (SurfaceType)(pServerDE->GetObjectUserFlags(hObject) >> 24);
}
return eType;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: TiltVectorToPlane
//
// PURPOSE: Tilts a vector so that it is perpendicular to a plane's normal.
//
// ----------------------------------------------------------------------- //
void TiltVectorToPlane(DVector *pVec, DVector *pNormal)
{
DVector q, slope;
// Get slope along vector...
VEC_CROSS(q, *pNormal, *pVec);
if(VEC_MAGSQR(q) > 0.001f)
{
VEC_NORM(q);
VEC_CROSS(slope, q, *pNormal);
// Fix vector along slope...
VEC_MULSCALAR(*pVec, slope, VEC_MAG(*pVec));
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: SendSoundTrigger
//
// PURPOSE: Sends a sound trigger message to all AIs in the radius
//
// ----------------------------------------------------------------------- //
void SendSoundTrigger(HOBJECT hSender, int nId, DVector vPos, DFLOAT fRadius)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return;
fRadius = fRadius * fRadius; // So we can compare squares
HOBJECT hObject;
char szTemp[64];
DVector vAIPos;
DLink* pLink = AI_Mgr::m_CabalHead.m_pNext;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -