static void CreateServerMark(CLIENTWEAPONFX & theStruct)
{
	AMMO* pAmmo = g_pWeaponMgr->GetAmmo(theStruct.nAmmoId);
	if (!pAmmo) return;

	// If this isn't a GameBase object, return...

	if (!IsGameBase(theStruct.hObj)) return;

	// See if we should create a mark, or simply move one of the GameBase's
	// marks.

	// If the GameBase has the max number of marks or this mark is very close
	// to a pre-existing mark, just move that mark to the new position.

    GameBase* pObj = (GameBase*) g_pLTServer->HandleToObject(theStruct.hObj);
	if (!pObj) return;

    HOBJECT hMoveObj = LTNULL;
    HOBJECT hFarObj  = LTNULL;

	ObjectList* pMarkList = pObj->GetMarkList();
	if (pMarkList)
	{
        uint8 nNumMarks = pMarkList->m_nInList;
		ObjectLink* pLink = pMarkList->m_pFirstLink;

        LTFLOAT  fClosestMarkDist  = REGION_DIAMETER;
        LTFLOAT  fFarthestMarkDist = 0.0f;
        uint8   nNumInRegion      = 0;
        LTVector vPos;

		for (int i=0; i < nNumMarks && pLink; i++)
		{
			if (pLink->m_hObject)
			{
				HATTACHMENT hAttachment;
                if (LT_OK == g_pLTServer->FindAttachment(theStruct.hObj, pLink->m_hObject, &hAttachment))
				{
					LTransform transform;
                    g_pLTServer->Common()->GetAttachmentTransform(hAttachment, transform, LTTRUE);

					vPos = transform.m_Pos;
				}

                LTFLOAT fDist = VEC_DISTSQR(vPos, theStruct.vPos);
				if (fDist < REGION_DIAMETER)
				{
					if (fDist < fClosestMarkDist)
					{
						fClosestMarkDist = fDist;
						hMoveObj = pLink->m_hObject;
					}

					if (++nNumInRegion > MAX_MARKS_IN_REGION)
					{
						// Just move this mark to the correct pos...
						hMoveObj = hMoveObj ? hMoveObj : pLink->m_hObject;
						break;
					}
				}

				if (fDist > fFarthestMarkDist)
				{
					fFarthestMarkDist = fDist;
					hFarObj = pLink->m_hObject;
				}
			}

			pLink = pLink->m_pNext;
		}

		// If we've got the max number of marks on this object, just move
		// the closest one to the new position...

		if (nNumMarks >= MAX_MARKS_PER_OBJECT)
		{
			hMoveObj = hMoveObj ? hMoveObj : (hFarObj ? hFarObj : pMarkList->m_pFirstLink->m_hObject);
		}
		else
		{
            hMoveObj = LTNULL; // Need to create one...
		}
	}

	// Re-setup the object to move it...

	if (hMoveObj && IsKindOf(hMoveObj, "CServerMark"))
	{
        CServerMark* pMoveMark = (CServerMark*) g_pLTServer->HandleToObject(hMoveObj);
		if (!pMoveMark) return;

		// Since this mark is already attached to pObj, remove the attachment
		// (since CServerMark::Setup() will re-attach it)...

		HATTACHMENT hAttachment;
        if (LT_OK == g_pLTServer->FindAttachment(theStruct.hObj, hMoveObj, &hAttachment))
		{
            g_pLTServer->RemoveAttachment(hAttachment);
		}

        pMoveMark->Setup((CLIENTWEAPONFX)theStruct);
		return;
	}


	// Okay, no luck, need to create a new mark...

	ObjectCreateStruct createStruct;
	INIT_OBJECTCREATESTRUCT(createStruct);

    LTFLOAT fScaleAdjust = 1.0f;
	if (!GetImpactSprite((SurfaceType)theStruct.nSurfaceType, fScaleAdjust,
		theStruct.nAmmoId, createStruct.m_Filename, ARRAY_LEN(createStruct.m_Filename)))
	{
		return;
	}

	createStruct.m_ObjectType = OT_SPRITE;
	createStruct.m_Flags = FLAG_VISIBLE | FLAG_NOLIGHT | FLAG_ROTATEABLESPRITE;
	createStruct.m_Pos = theStruct.vPos;

    g_pLTServer->AlignRotation(&(createStruct.m_Rotation), &((LTVector)theStruct.vSurfaceNormal), LTNULL);


    HCLASS hClass = g_pLTServer->GetClass("CServerMark");
    CServerMark* pMark = (CServerMark*) g_pLTServer->CreateObject(hClass, &createStruct);
	if (!pMark) return;

	// Add the mark to the object...

	pObj->AddMark(pMark->m_hObject);


	// Randomly adjust the mark's scale to add a bit o spice...

	if (pAmmo->pImpactFX)
	{
        LTFLOAT fScale = fScaleAdjust * pAmmo->pImpactFX->fMarkScale;

        LTVector vScale;
		VEC_SET(vScale, fScale, fScale, fScale);
        g_pLTServer->ScaleObject(pMark->m_hObject, &vScale);
	}

	pMark->Setup((CLIENTWEAPONFX)theStruct);
}
Beispiel #2
0
LTBOOL CSearchLightFX::CreateObject(ILTClient* pClientDE)
{
    if (!CSpecialFX::CreateObject(pClientDE) || !m_hServerObject) return LTFALSE;

	ObjectCreateStruct createStruct;
	INIT_OBJECTCREATESTRUCT(createStruct);

	// Create the beam model...

	m_pClientDE->GetObjectPos(m_hServerObject, &(createStruct.m_Pos));
	createStruct.m_ObjectType = OT_MODEL;

	CString str = g_pClientButeMgr->GetSpecialFXAttributeString("SearchBeam");
    if (str.IsEmpty()) return LTFALSE;

	SAFE_STRCPY(createStruct.m_Filename, (char *)(LPCSTR)str);

	str = g_pClientButeMgr->GetSpecialFXAttributeString("SearchSkin");
	if (!str.IsEmpty())
	{
		SAFE_STRCPY(createStruct.m_SkinName, (char *)(LPCSTR)str);
	}

	createStruct.m_Flags = FLAG_VISIBLE | FLAG_NOLIGHT;

	if (m_cs.bBeamAdditive)
	{
		createStruct.m_Flags2 = FLAG2_ADDITIVE;
	}

	m_hBeam = m_pClientDE->CreateObject(&createStruct);
    if (!m_hBeam) return LTFALSE;

    LTFLOAT r, g, b, a;
	m_pClientDE->GetObjectColor(m_hBeam, &r, &g, &b, &a);
	r = g = b = 1.0f;
	m_pClientDE->SetObjectColor(m_hBeam, r, g, b, m_cs.fBeamAlpha);


	// Create the dynamic light...

	if (m_cs.fLightRadius > 1.0f)
	{
		createStruct.m_ObjectType = OT_LIGHT;
		createStruct.m_Flags = FLAG_VISIBLE | FLAG_DONTLIGHTBACKFACING;

		m_hLight = m_pClientDE->CreateObject(&createStruct);
        if (!m_hLight) return LTFALSE;

		m_pClientDE->SetLightColor(m_hLight, m_cs.vLightColor.x, m_cs.vLightColor.y, m_cs.vLightColor.z);
		m_pClientDE->SetLightRadius(m_hLight, m_cs.fLightRadius);
	}


	// Create the lens flare...

	LENSFLARECREATESTRUCT lens = m_cs.lens;

	lens.hServerObj			= m_hServerObject;
    lens.bInSkyBox          = LTFALSE;
    lens.bCreateSprite      = LTTRUE;
    lens.bSpriteOnly        = LTTRUE;
    lens.bUseObjectAngle    = LTTRUE;

	if (!m_LensFlare.Init(&lens) || !m_LensFlare.CreateObject(m_pClientDE))
	{
        return LTFALSE;
	}

    return LTTRUE;
}
Beispiel #3
0
bool CSnowFXAirspace::Activate( float detail )
{
	// update the LOD
	ASSERT( detail > 0.0f && detail <= 1.0f );
	m_LOD = detail;

	// don't do anything else if already active
	if( m_Active )
		return true;

#ifdef SNOWFX_PROFILE_ACTIVATION
	LARGE_INTEGER pcStart, pcEnd, pcFreq;
	QueryPerformanceFrequency( &pcFreq );
	QueryPerformanceCounter( &pcStart );
#endif

	if( !m_Parent->m_ParticleMgr.AllocateParticles( m_NumParticles, m_Particles ) )
		return false;

	m_Active = true;

	// allocate space for the particle minimum elevation array
	m_MinY = debug_newa( float, m_NumParticles );

	// initialize the minimum elevation array
	for( uint32 i = 0; i < m_NumParticles; i++ )
	{
		m_MinY[i] = m_Pos.y - m_Dims.y;
	}

	// adjust minimum elevation array by blockers
	for( std::vector<uint32>::iterator it = m_Blockers.begin(); it != m_Blockers.end(); it++ )
	{
		float t;
		LTPlane blockerPlane;
		uint32 numEdges;
		LTPlane* edgePlanes;

		// get the current particle blocker
		m_Parent->m_pClientDE->GetParticleBlockerEdgesXZ( *it, blockerPlane, numEdges, edgePlanes );

		// don't consider nearly vertical blockers
		if( fabs(blockerPlane.m_Normal.y) < 0.00001 )
			continue;

		// precalculate some stuff for plane intersection calculations
		float dc = -1.0f / blockerPlane.m_Normal.y;
		float xc = blockerPlane.m_Normal.x * dc;
		float zc = blockerPlane.m_Normal.z * dc;
		dc *= blockerPlane.m_Dist;

		LTVector curPos;
		curPos.y = 0.0f;

		// check all particles against this blocker
		for( uint32 i = 0; i < m_NumParticles; i++ )
		{
			curPos.x = m_Pos.x + m_Particles[i].pos.x * m_Dims.x;
			curPos.z = m_Pos.z + m_Particles[i].pos.z * m_Dims.z;

			// check if the xz of the particle is within the projected xz polygon
			if( TestParticleBlocker( curPos, numEdges, const_cast<const LTPlane *&>(edgePlanes) ) )
			{
				// find where the particle hits the blocker
				t = dc + curPos.x * xc + curPos.z * zc;
				if( t > m_MinY[i] )
					m_MinY[i] = t;
			}
		}
	}

	// create the volume effect (either reusing an old one, or creating a new one)
	if( !m_Parent->freeEffects.empty() )
	{
		m_Effect = HOBJECT(*m_Parent->freeEffects.begin());
		m_Parent->freeEffects.pop_front();

		m_Parent->m_pClientDE->SetObjectPos( m_Effect, &m_Pos );
		g_pCommonLT->SetObjectFlags( m_Effect, OFT_Flags, FLAG_VISIBLE, FLAG_VISIBLE );
	}
	else
	{
		ObjectCreateStruct ocs;
		INIT_OBJECTCREATESTRUCT( ocs );
		ocs.m_ObjectType = OT_VOLUMEEFFECT;
		ocs.m_Flags = FLAG_VISIBLE;
		ocs.m_Flags2 = FLAG2_FORCETRANSLUCENT;
		ocs.m_Pos = m_Pos;
		ocs.m_Rotation.Init();

		m_Effect = m_Parent->m_pClientDE->CreateObject( &ocs );
	}

	VolumeEffectInfo vei;
	vei.m_EffectType = VolumeEffectInfo::kDynamicParticles;
	vei.m_Dims = m_Dims;
	vei.m_DPPrimitive = VolumeEffectInfo::kTrilist;
	vei.m_DPLighting = m_Parent->m_bUseLighting ? VolumeEffectInfo::kSinglePointNonDirectional : VolumeEffectInfo::kNone;
	vei.m_DPLightConstant = 0xffffffff;
	vei.m_DPSaturate = m_Parent->m_bUseSaturate;
	vei.m_DPTextureName = m_Parent->m_pClientDE->GetStringData( m_Parent->m_hstrTextureName );
	vei.m_DPUserData = this;
	vei.m_DPUpdateFn = &SnowFXFillVertexBuffer;

	m_Parent->m_pClientDE->SetupVolumeEffect( m_Effect, vei );

	m_Parent->activeAirspaces.insert( this );

#ifdef SNOWFX_PROFILE_ACTIVATION
	QueryPerformanceCounter( &pcEnd );
	double pcTime = (double)(pcEnd.QuadPart - pcStart.QuadPart) * (double)1000.0 / (double)pcFreq.QuadPart;
	g_pLTClient->CPrint( " Snow Activation: %8.6f ms", pcTime );
#endif
	
	return true;
}
Beispiel #4
0
bool CFallingStuffFX::Update(float tmFrameTime)
{
    // Base class update first

    m_vLastPos = m_vPos;

    if (!CBaseFX::Update(tmFrameTime))
        return false;

    //increment our emission time by the elapsed frame time
    m_tmElapsedEmission += tmFrameTime;

    if (!IsShuttingDown() && !IsSuspended() && (m_tmElapsedEmission > GetProps()->m_tmFallingStuffFXEmission))
    {
        ObjectCreateStruct ocs;
        INIT_OBJECTCREATESTRUCT(ocs);

        LTVector vScale;
        vScale.Init(m_scale, m_scale, m_scale);

        LTVector vInterp;
        LTVector vInterpCur  = m_vPos;

        // Calculate interpolant for particle system

        if (GetProps()->m_nFallingStuffFXEmission)
        {
            vInterp = m_vPos - m_vLastPos;
            vInterp /= (float)GetProps()->m_nFallingStuffFXEmission;
        }

        for (uint32 i = 0; i < GetProps()->m_nFallingStuffFXEmission; i ++)
        {
            ocs.m_ObjectType		= OT_SPRITE;
            ocs.m_Flags				= FLAG_VISIBLE | FLAG_NOLIGHT | FLAG_ROTATABLESPRITE;

            // Compute the initial position

            float xRand = GetProps()->m_fRadius * ((-10000.0f + (rand() % 20000)) / 10000.0f);
            float zRand = GetProps()->m_fRadius * ((-10000.0f + (rand() % 20000)) / 10000.0f);

            ocs.m_Pos = m_vPos + (m_vRight * xRand) + (m_vUp * zRand);

            ocs.m_Scale				= vScale;
            strcpy(ocs.m_Filename, GetProps()->m_sSpriteName);

            // Move the start point

            vInterpCur += vInterp;

            HLOCALOBJ hNewSprite = m_pLTClient->CreateObject(&ocs);

            if (hNewSprite)
            {
                // Create a new sprite

                FALLING_THING *pNewSprite = debug_new( FALLING_THING );

                if (GetProps()->m_nImpactCreate)
                {
                    if (g_dwSplash > (uint32)GetProps()->m_nImpactCreate)
                    {
                        pNewSprite->m_bSplash = true;
                        g_dwSplash = 0;
                    }
                    else
                    {
                        pNewSprite->m_bSplash = false;
                    }
                }
                else
                {
                    pNewSprite->m_bSplash = false;
                }

                g_dwSplash ++;

                if (pNewSprite)
                {
                    LTVector v;

                    // Compute the initial velocity

                    v = m_vPlaneDir * GetProps()->m_fVel;

                    pNewSprite->m_hObject	= hNewSprite;
                    pNewSprite->m_vVel		= v;
                    pNewSprite->m_tmElapsed	= 0.0f;
                    pNewSprite->m_vPos		= ocs.m_Pos;
                    pNewSprite->m_vLastPos	= ocs.m_Pos;

                    m_collSprites.AddTail(pNewSprite);
                }
            }
        }

        m_tmElapsedEmission = 0.0f;

        // And store the last position

        m_vLastPos = m_vPos;
    }

    LTMatrix mSpin;

    if (GetProps()->m_bUseSpin)
    {
        // Setup rotation

        LTMatrix vRight;
        LTMatrix vUp;
        LTMatrix vForward;
        LTMatrix vTmp;

        Mat_SetupRot(&vRight, &m_vRight, m_xRot);
        Mat_SetupRot(&vUp, &m_vUp, m_yRot);
        Mat_SetupRot(&vForward, &m_vPlaneDir, m_zRot);

        MatMul(&vTmp, &vRight, &vUp);
        MatMul(&mSpin, &vTmp, &vForward);

        m_xRot += GetProps()->m_vRotAdd.x * tmFrameTime;
        m_yRot += GetProps()->m_vRotAdd.y * tmFrameTime;
        m_zRot += GetProps()->m_vRotAdd.z * tmFrameTime;
    }

    // Get the camera rotation

    LTRotation orient;
    m_pLTClient->GetObjectRotation(m_hCamera, &orient);

    LTRotation dRot(orient);

    LTVector vF = orient.Forward();

    float rot = (float)atan2(vF.x, vF.z);

    // Update the sprites....

    CLinkListNode<FALLING_THING *> *pNode = m_collSprites.GetHead();
    CLinkListNode<FALLING_THING *> *pDelNode;

    while (pNode)
    {
        pDelNode = NULL;

        FALLING_THING *pSprite = pNode->m_Data;

        //adjust our elapsed time
        pSprite->m_tmElapsed += tmFrameTime;

        // Check for expiration

        if (pSprite->m_tmElapsed > GetProps()->m_tmSpriteLifespan)
        {
            // Destroy this object

            m_pLTClient->RemoveObject(pSprite->m_hObject);

            pDelNode = pNode;
        }
        else
        {
            // Update !!

            pSprite->m_vLastPos = pSprite->m_vPos;

            pSprite->m_vPos += (pSprite->m_vVel * tmFrameTime);

            // Rotate if neccessary

            TVector3<float> vPos = pSprite->m_vPos;

            if (GetProps()->m_bUseSpin)
            {
                MatVMul_InPlace(&mSpin, &vPos);
            }

            // Add in wind

            vPos += (GetProps()->m_vWind * GetProps()->m_fWindAmount) * tmFrameTime;

            // Setup the new sprite position

            LTVector vPos2 = vPos;
            m_pLTClient->SetObjectPos(pSprite->m_hObject, &vPos2);


            // Setup the colour

            float r, g, b, a;

            m_pLTClient->GetObjectColor(pSprite->m_hObject, &r, &g, &b, &a);
            CalcColour(pSprite->m_tmElapsed, GetProps()->m_tmSpriteLifespan, &r, &g, &b, &a);
            m_pLTClient->SetObjectColor(pSprite->m_hObject, r, g, b, a);

            // Setup the scale

            float scale = 0.1f;

            CalcScale(pSprite->m_tmElapsed, GetProps()->m_tmSpriteLifespan, &scale);

            LTVector vScale;
            vScale.Init(scale, scale * GetProps()->m_fStretchMul, scale);
            m_pLTClient->SetObjectScale(pSprite->m_hObject, &vScale);

            // Setup the rotation

            dRot = LTRotation(0, 0, 0, 1);
            LTRotation orient(dRot);

            orient.Rotate( orient.Up(), rot );

            m_pLTClient->SetObjectRotation(pSprite->m_hObject, &orient);

            // Check to see if we need to start a splash sprite

            if (pSprite->m_bSplash)
            {
                ClientIntersectQuery ciq;
                ClientIntersectInfo  cii;

                ciq.m_From		= pSprite->m_vLastPos;
                ciq.m_To		= pSprite->m_vPos;

                if ((GetProps()->m_sImpactSpriteName[0]) && (m_pLTClient->IntersectSegment(&ciq, &cii)))
                {
                    // Create a splash sprite

                    SPLASH *pSplash = debug_new( SPLASH );

                    ObjectCreateStruct ocs;
                    INIT_OBJECTCREATESTRUCT(ocs);

                    LTVector vScale;
                    vScale.Init(0.0f, 0.0f, 0.0f);

                    ocs.m_ObjectType = OT_SPRITE;
                    ocs.m_Flags		 = FLAG_VISIBLE | FLAG_ROTATABLESPRITE | FLAG_NOLIGHT;
                    ocs.m_Pos		 = cii.m_Point + (cii.m_Plane.m_Normal * 2.0f);
                    ocs.m_Scale		 = vScale;

                    LTRotation dOrient( cii.m_Plane.m_Normal, LTVector(0.0f, 1.0f, 0.0f) );

                    strcpy(ocs.m_Filename, GetProps()->m_sImpactSpriteName);

                    pSplash->m_hObject = m_pLTClient->CreateObject(&ocs);
                    pSplash->m_scale = 0.0f;

                    LTRotation orient(dRot);
                    m_pLTClient->SetObjectRotation(pSplash->m_hObject, &orient);

                    pSplash->m_tmElapsed = 0.0f;

                    m_collSplashes.AddTail(pSplash);

                    // Destroy this object

                    m_pLTClient->RemoveObject(pSprite->m_hObject);

                    // Delete the sprite

                    pDelNode = pNode;
                }
            }
        }

        pNode = pNode->m_pNext;

        if (pDelNode) m_collSprites.Remove(pDelNode);
    }

    // Update our splashes

    CLinkListNode<SPLASH *> *pSplashNode = m_collSplashes.GetHead();

    while (pSplashNode)
    {
        CLinkListNode<SPLASH *> *pDelNode = NULL;

        SPLASH *pSplash = pSplashNode->m_Data;

        //update the elapsed time on the splash
        pSplash->m_tmElapsed += tmFrameTime;

        // Calculate the new scale

        float scale = GetProps()->m_fImpactScale1 + ((GetProps()->m_fImpactScale2 - GetProps()->m_fImpactScale1) * (pSplash->m_tmElapsed / GetProps()->m_tmImpactLifespan));

        LTVector vScale(scale, scale, scale);
        m_pLTClient->SetObjectScale(pSplash->m_hObject, &vScale);

        float r, g, b, a;

        m_pLTClient->GetObjectColor(pSplash->m_hObject, &r, &g, &b, &a);

        a = (float)(int)(pSplash->m_tmElapsed / GetProps()->m_tmImpactLifespan);
        if (a < 0.0f) a = 0.0f;
        if (a > 1.0f) a = 1.0f;

        m_pLTClient->SetObjectColor(pSplash->m_hObject, r, g, b, a);

        if (pSplash->m_tmElapsed > GetProps()->m_tmImpactLifespan)
        {
            m_pLTClient->RemoveObject(pSplash->m_hObject);
            pDelNode = pSplashNode;
        }

        pSplashNode = pSplashNode->m_pNext;

        if (pDelNode) m_collSplashes.Remove(pDelNode);
    }

    // Success !!

    return true;
}
Beispiel #5
0
void SecurityCamera::SetupDisabledState()
{
	if (m_eState == eStateDisabled || m_hDisablerModel) return;

    g_pCommonLT->SetObjectFlags(m_hObject, OFT_User, 0, USRFLG_GADGET_CAMERA_DISABLER);

	// Create the camera disabler model, and attach it to the camera...

	ObjectCreateStruct theStruct;
	INIT_OBJECTCREATESTRUCT(theStruct);

	theStruct.m_Pos = m_vPos;

	char szFile[128] = {0};
	g_pServerButeMgr->GetSecurityCameraString( SCS_DISABLER_FILENAME, szFile, ARRAY_LEN( szFile ));

	if( szFile[0] )
		SAFE_STRCPY(theStruct.m_Filename, szFile);

	szFile[0] = '\0';
	g_pServerButeMgr->GetSecurityCameraString( SCS_DISABLER_SKIN, szFile, ARRAY_LEN( szFile ));

	if( szFile[0] )
		SAFE_STRCPY(theStruct.m_SkinName, szFile);

	theStruct.m_Flags = FLAG_VISIBLE | FLAG_GOTHRUWORLD;
	theStruct.m_ObjectType  = OT_MODEL;

    HCLASS hClass = g_pLTServer->GetClass("BaseClass");
    LPBASECLASS pModel = g_pLTServer->CreateObject(hClass, &theStruct);
	if (!pModel) return;

	m_hDisablerModel = pModel->m_hObject;

	// Don't eat ticks please...
	::SetNextUpdate(m_hDisablerModel, UPDATE_NEVER);

	// Attach the model to the the camera...

    LTVector vOffset(0, 0, 0);
    LTRotation rOffset;

	HATTACHMENT hAttachment;
    LTRESULT dRes = g_pLTServer->CreateAttachment(m_hObject, m_hDisablerModel, "Disabler",
											     &vOffset, &rOffset, &hAttachment);
    if (dRes != LT_OK)
	{
        g_pLTServer->RemoveObject(m_hDisablerModel);
        m_hDisablerModel = LTNULL;
		return;
	}

	// Set the Disabler's animation...

    HMODELANIM hAni = g_pLTServer->GetAnimIndex(m_hDisablerModel, "Activate");
	if (hAni)
	{
        g_pLTServer->SetModelLooping(m_hDisablerModel, LTFALSE);
        g_pLTServer->SetModelAnimation(m_hDisablerModel, hAni);
	}


	// Play the activate sound...

	szFile[0] = '\0';
	g_pServerButeMgr->GetSecurityCameraString( SCS_DISABLER_SOUND, szFile, ARRAY_LEN( szFile ));

	LTFLOAT	fRadius = g_pServerButeMgr->GetSecurityCameraFloat( SCS_SOUND_RADIUS );
	
	if( szFile )
		g_pServerSoundMgr->PlaySoundFromPos(m_vPos, szFile, fRadius, SOUNDPRIORITY_MISC_LOW);


	// Camera is now disabled...

    m_bDisabled = LTTRUE;
}