void CMuzzleFlashFX::SetRot(LTRotation rRot) { if (!m_pClientDE) return; HOBJECT hObj; if (m_bUsingParticles) { hObj = m_Particle.GetObject(); if (hObj) { if (g_vtReallyClose.GetFloat()) { LTRotation rInitRot; rInitRot.Init(); m_pClientDE->SetObjectRotation(hObj, &rInitRot); } else { m_pClientDE->SetObjectRotation(hObj, &rRot); } } } if (m_bUsingLight) { hObj = m_Light.GetObject(); if (hObj) { m_pClientDE->SetObjectRotation(hObj, &rRot); } } if (m_bUsingScale) { hObj = m_Scale.GetObject(); if (hObj) { LTRotation rTempRot = rRot; // Camera relative rotation... if (m_cs.bPlayerView) { rTempRot.Init(); } m_pClientDE->SetObjectRotation(hObj, &rTempRot); } } }
void GameBase::CreateBoundingBox() { if (m_hDimsBox) return; if (!g_vtDimsAlpha.IsInitted()) { g_vtDimsAlpha.Init(g_pLTServer, "DimsAlpha", LTNULL, 1.0f); } ObjectCreateStruct theStruct; INIT_OBJECTCREATESTRUCT(theStruct); LTVector vPos; g_pLTServer->GetObjectPos(m_hObject, &vPos); theStruct.m_Pos = vPos; SAFE_STRCPY(theStruct.m_Filename, "Models\\1x1_square.abc"); SAFE_STRCPY(theStruct.m_SkinName, "Models\\1x1_square.dtx"); theStruct.m_Flags = FLAG_VISIBLE | FLAG_NOLIGHT | FLAG_GOTHRUWORLD; theStruct.m_ObjectType = OT_MODEL; HCLASS hClass = g_pLTServer->GetClass("BaseClass"); LPBASECLASS pModel = g_pLTServer->CreateObject(hClass, &theStruct); if (pModel) { m_hDimsBox = pModel->m_hObject; LTVector vDims; g_pLTServer->GetObjectDims(m_hObject, &vDims); LTVector vScale; VEC_DIVSCALAR(vScale, vDims, 0.5f); g_pLTServer->ScaleObject(m_hDimsBox, &vScale); } LTVector vOffset; LTRotation rOffset; vOffset.Init(); rOffset.Init(); HATTACHMENT hAttachment; LTRESULT dRes = g_pLTServer->CreateAttachment(m_hObject, m_hDimsBox, LTNULL, &vOffset, &rOffset, &hAttachment); if (dRes != LT_OK) { g_pLTServer->RemoveObject(m_hDimsBox); m_hDimsBox = LTNULL; } LTVector vColor = GetBoundingBoxColor(); g_pLTServer->SetObjectColor(m_hDimsBox, vColor.x, vColor.y, vColor.z, g_vtDimsAlpha.GetFloat()); }
bool WorldModel::AttachServerMark( CServerMark& mark, CLIENTWEAPONFX & theStruct) { LTransform globalTransform, parentTransform, localTransform; ILTTransform *pTransformLT; LTVector vParentPos, vOffset; LTRotation rParentRot, rRot; LTRotation rOffset; pTransformLT = g_pLTServer->GetTransformLT(); // Attach the mark to the parent object... // Figure out what the rotation we want is. rOffset.Init(); rRot = LTRotation(theStruct.vSurfaceNormal, LTVector(0.0f, 1.0f, 0.0f)); // MD // Ok, now we have the transform in global space but attachments are specified in // local space (so they can move as the object moves and rotates). // Set the global LTransform. pTransformLT->Set(globalTransform, theStruct.vPos, rRot); // Get the object's transform. g_pLTServer->GetObjectPos( m_hObject, &vParentPos); g_pLTServer->GetObjectRotation( m_hObject, &rParentRot); parentTransform.m_Pos = vParentPos; parentTransform.m_Rot = rParentRot; parentTransform.m_Scale.Init(1,1,1); globalTransform.m_Scale.Init(1,1,1); // Get the offset. pTransformLT->Difference(localTransform, globalTransform, parentTransform); vOffset = localTransform.m_Pos; rOffset = localTransform.m_Rot; HATTACHMENT hAttachment = NULL; LTRESULT dRes = g_pLTServer->CreateAttachment( m_hObject, mark.m_hObject, LTNULL, &vOffset, &rOffset, &hAttachment); if (dRes != LT_OK) { return false; } // Add to the attachment list. LTObjRefNotifier ref( *this ); ref = mark.m_hObject; m_AttachmentList.push_back( ref ); return true; }
void CCoin::RotateToRest() { if ( !m_bRotatedToRest ) { char szSpawn[1024]; sprintf(szSpawn, "WeaponItem Gravity 0;AmmoAmount 1;WeaponType Coin;AmmoType Coin"); LTVector vPos; g_pLTServer->GetObjectPos(m_hObject, &vPos); vPos.y += 2.0f; // This offsets us from the floor a bit so we don't pop through when WeaponItem sets its dims. LTRotation rRot; rRot.Init(); BaseClass* pObj = SpawnObject(szSpawn, vPos, rRot); if ( pObj && pObj->m_hObject ) { g_pLTServer->SetAcceleration(pObj->m_hObject, <Vector(0,0,0)); g_pLTServer->SetVelocity(pObj->m_hObject, <Vector(0,0,0)); } g_pLTServer->SetObjectFlags(m_hObject, g_pLTServer->GetObjectFlags(m_hObject)&~FLAG_VISIBLE); } CGrenade::RotateToRest(); if ( IsCharacter(m_hFiredFrom) ) { LTVector vPosition; g_pLTServer->GetObjectPos(m_hObject, &vPosition); CCharacter* pCharacter = (CCharacter*)g_pLTServer->HandleToObject(m_hFiredFrom); CharCoinInfo cinfo; cinfo.fTime = g_pLTServer->GetTime(); cinfo.eSurfaceType = m_eLastHitSurface; cinfo.vPosition = vPosition; SURFACE* pSurf = g_pSurfaceMgr->GetSurface(m_eLastHitSurface); _ASSERT(pSurf); if (pSurf) { cinfo.fVolume = pSurf->fMovementNoiseModifier; } else { cinfo.fVolume = 1.0f; } pCharacter->SetLastCoinInfo(&cinfo); } }
LTBOOL CBaseParticleSystemFX::CreateObject(ILTClient *pClientDE) { if (!CSpecialFX::CreateObject(pClientDE)) return LTFALSE; LTVector vPos = m_vPos; LTRotation rRot; rRot.Init(); // Use server object position if a position wasn't specified... if (m_hServerObject) { LTVector vZero(0, 0, 0), vServObjPos; if (vPos.Equals(vZero)) { pClientDE->GetObjectPos(m_hServerObject, &vServObjPos); vPos = vServObjPos; } else { m_basecs.bClientControlsPos = LTTRUE; } // Calculate our offset from the server object... m_vPosOffset = vPos - vServObjPos; } // Use the specified rotation if applicable if (!m_rRot.IsIdentity()) { rRot = m_rRot; } ObjectCreateStruct createStruct; INIT_OBJECTCREATESTRUCT(createStruct); createStruct.m_ObjectType = OT_PARTICLESYSTEM; createStruct.m_Flags = FLAG_VISIBLE | FLAG_UPDATEUNSEEN | FLAG_FOGDISABLE; createStruct.m_Pos = vPos; createStruct.m_Rotation = rRot; m_hObject = m_pClientDE->CreateObject(&createStruct); // Setup the ParticleSystem... return SetupSystem(); }
void SecurityCamera::CreateLight() { // Create the light...and attach it to the camera... ObjectCreateStruct theStruct; INIT_OBJECTCREATESTRUCT(theStruct); theStruct.m_Pos = m_vPos; g_pServerButeMgr->GetSecurityCameraString("GreenLight", theStruct.m_Filename, ARRAY_LEN(theStruct.m_Filename)); theStruct.m_Flags = FLAG_VISIBLE | FLAG_GLOWSPRITE; theStruct.m_Flags2 = FLAG2_ADDITIVE; theStruct.m_ObjectType = OT_SPRITE; HCLASS hClass = g_pLTServer->GetClass("BaseClass"); LPBASECLASS pSprite = g_pLTServer->CreateObject(hClass, &theStruct); if (!pSprite) return; m_hLight = pSprite->m_hObject; LTVector vScale(1, 1, 1); vScale.x = g_pServerButeMgr->GetSecurityCameraFloat("LightScale"); vScale.y = vScale.x; g_pLTServer->ScaleObject(m_hLight, &vScale); // Attach the sprite to the the camera... LTVector vOffset(0, 0, 0); LTRotation rOffset; rOffset.Init(); HATTACHMENT hAttachment; LTRESULT dRes = g_pLTServer->CreateAttachment(m_hObject, m_hLight, "Light", &vOffset, &rOffset, &hAttachment); if (dRes != LT_OK) { g_pLTServer->RemoveObject(m_hLight); m_hLight = LTNULL; return; } }
void CNodeController::UpdateHeadFollowPosControl(NCSTRUCT *pNodeControl) { LTVector vPos; LTRotation rRot; LTransform transform; LTVector vU, vR, vF; //---------------------------------------------------------------------- // Get information about the control node... // *** NOTE: On the head node... vU faces forward, vR faces down, vF faces right *** // Get access to the controls... ILTMath *pMathLT = g_pLTClient->GetMathLT(); ILTModel *pModelLT = g_pLTClient->GetModelLT(); ILTTransform *pTransformLT = g_pLTClient->GetTransformLT(); // Get the transform of the node we're controlling pModelLT->GetNodeTransform(GetCFX()->GetServerObj(), m_aNodes[pNodeControl->eModelNode].hModelNode, transform, LTTRUE); // Decompose the transform into the position and rotation pTransformLT->Get(transform, vPos, rRot); pMathLT->GetRotationVectors(rRot, vR, vU, vF); // Get information about the follow position... LTVector vObjPos = pNodeControl->vFollowPos; // Turn the follow control off if the expire time has past if(pNodeControl->fFollowExpireTime <= 0.0f) { pNodeControl->fFollowExpireTime = 0.0f; pNodeControl->bFollowOn = LTFALSE; } else pNodeControl->fFollowExpireTime -= g_pGameClientShell->GetFrameTime(); //---------------------------------------------------------------------- // Setup the rotation matrix to directly follow the destination position // Get the direction that we're going to face... LTVector vDir = vObjPos - vPos; // Setup some temp vectors that are on the x/z plane... LTVector vTempU, vTempF, vTempDir; vTempU = vU; vTempU.y = 0.0f; vTempF = vF; vTempF.y = 0.0f; vTempDir = vDir; vTempDir.y = 0.0f; VEC_NORM(vTempU); VEC_NORM(vTempF); VEC_NORM(vTempDir); // Get the dot products between the dir vector and the up and forward to determine the rotation angles LTFLOAT fDotUDir = VEC_DOT(vTempU, vTempDir); LTFLOAT fDotFDir = VEC_DOT(vTempF, vTempDir); LTFLOAT fDotRDir = 0.0f; // Init the vectors to get a rotation matrix from... LTVector vRotAxisR(1.0f, 0.0f, 0.0f); // Get the first rotation angle LTFLOAT fAngle1 = pNodeControl->bFollowOn ? fDotUDir : 1.0f; if(fAngle1 < -0.1f) fAngle1 = -0.1f; // HACK! Limit the head rotation fAngle1 = (1.0f - fAngle1) * MATH_HALFPI; if(fDotFDir < 0.0f) fAngle1 *= -1.0f; // Do a full rotation around the first axis so we can get an angle for the second axis LTFLOAT fTempAngle = pNodeControl->bFollowOn ? ((1.0f - fDotUDir) * MATH_HALFPI) : 0.0f; pMathLT->RotateAroundAxis(rRot, vR, (fDotFDir < 0.0f) ? -fTempAngle : fTempAngle); pMathLT->GetRotationVectors(rRot, vR, vU, vF); VEC_NORM(vDir); fDotUDir = VEC_DOT(vU, vDir); fDotRDir = VEC_DOT(vR, vDir); // Get the second rotation angle LTFLOAT fAngle2 = pNodeControl->bFollowOn ? fDotUDir : 1.0f; if(fAngle2 < 0.25f) fAngle2 = 0.25f; // HACK! Limit the head rotation fAngle2 = (1.0f - fAngle2) * MATH_HALFPI; if(fDotRDir > 0.0f) fAngle2 *= -1.0f; // Calculate a max rotation value LTFLOAT fRotMax = (pNodeControl->fFollowRate * g_pGameClientShell->GetFrameTime() / 180.0f) * MATH_PI; // Interpolate the angles based off the previous angle if(fAngle1 > pNodeControl->vFollowAngles.y + fRotMax) fAngle1 = pNodeControl->vFollowAngles.y + fRotMax; else if(fAngle1 < pNodeControl->vFollowAngles.y - fRotMax) fAngle1 = pNodeControl->vFollowAngles.y - fRotMax; if(fAngle2 > pNodeControl->vFollowAngles.x + fRotMax) fAngle2 = pNodeControl->vFollowAngles.x + fRotMax; else if(fAngle2 < pNodeControl->vFollowAngles.x - fRotMax) fAngle2 = pNodeControl->vFollowAngles.x - fRotMax; // Create a new rotation and rotate around each controlled axis LTRotation rNewRot; rNewRot.Init(); pMathLT->RotateAroundAxis(rNewRot, vRotAxisR, fAngle1); pNodeControl->vFollowAngles.y = fAngle1; pMathLT->GetRotationVectors(rNewRot, vR, vU, vF); pMathLT->RotateAroundAxis(rNewRot, vF, fAngle2); pNodeControl->vFollowAngles.x = fAngle2; // If we're turned off and back at the start rotation... make the control invalid if(!pNodeControl->bFollowOn && pNodeControl->vFollowAngles.x == 0.0f && pNodeControl->vFollowAngles.y == 0.0f) { pNodeControl->bValid = LTFALSE; return; } // Create a rotation matrix and apply it to the current offset matrix LTMatrix m1; pMathLT->SetupRotationMatrix(m1, rNewRot); m_aNodes[pNodeControl->eModelNode].matTransform = m_aNodes[pNodeControl->eModelNode].matTransform * m1; }
void CNodeController::UpdateScriptControl(NCSTRUCT *pNodeControl) { LTFLOAT fTime = g_pLTClient->GetTime() - pNodeControl->fScriptTime; ModelNScript eScript = (ModelNScript)pNodeControl->nScript; int nCurPt = pNodeControl->nCurrentScriptPt; int nLastPt = pNodeControl->nLastScriptPt; // g_pLTClient->CPrint("Running node script!"); // Check to see if the script is over... and make it invalid if so if(fTime > g_pModelButeMgr->GetNScriptPtTime(eScript, nLastPt)) { // g_pLTClient->CPrint("Ending node script!"); pNodeControl->bValid = LTFALSE; return; } // Get access to the controls... ILTMath *pMathLT = g_pLTClient->GetMathLT(); // Get the current script point while(fTime > g_pModelButeMgr->GetNScriptPtTime(eScript, nCurPt)) nCurPt++; // Calculate the scale value from the last position to the current LTFLOAT fPtTime1 = g_pModelButeMgr->GetNScriptPtTime(eScript, nCurPt - 1); LTFLOAT fPtTime2 = g_pModelButeMgr->GetNScriptPtTime(eScript, nCurPt); LTFLOAT fScale = (fTime - fPtTime1) / (fPtTime2 - fPtTime1); //---------------------------------------------------------------------------- // Setup the initial position vector LTVector vPos; // Get a direction vector from the last position to the current LTVector vPosDir = g_pModelButeMgr->GetNScriptPtPosOffset(eScript, nCurPt) - g_pModelButeMgr->GetNScriptPtPosOffset(eScript, nCurPt - 1); VEC_MULSCALAR(vPosDir, vPosDir, fScale); vPos = g_pModelButeMgr->GetNScriptPtPosOffset(eScript, nCurPt - 1) + vPosDir; //---------------------------------------------------------------------------- // Setup the initial rotation vector LTVector vRot; // Get a direction rotation from the last position to the current LTVector vRotDir = g_pModelButeMgr->GetNScriptPtRotOffset(eScript, nCurPt) - g_pModelButeMgr->GetNScriptPtRotOffset(eScript, nCurPt - 1); VEC_MULSCALAR(vRotDir, vRotDir, fScale); vRot = g_pModelButeMgr->GetNScriptPtRotOffset(eScript, nCurPt - 1) + vRotDir; // Calculate the rotation... LTRotation rRot; LTVector vR, vU, vF; rRot.Init(); pMathLT->GetRotationVectors(rRot, vR, vU, vF); pMathLT->RotateAroundAxis(rRot, vR, vRot.x); pMathLT->RotateAroundAxis(rRot, vU, vRot.y); pMathLT->RotateAroundAxis(rRot, vF, vRot.z); //---------------------------------------------------------------------------- // Setup the matrix using the offset position and rotation LTMatrix m1; pMathLT->SetupTransformationMatrix(m1, vPos, rRot); m_aNodes[pNodeControl->eModelNode].matTransform = m_aNodes[pNodeControl->eModelNode].matTransform * m1; }
void CNodeController::UpdateLipSyncControl(NCSTRUCT *pNodeControl) { // Make sure the sound handle is valid and check to see if the sound is done... if(!pNodeControl->hLipSyncSound || g_pLTClient->IsDone(pNodeControl->hLipSyncSound)) { g_pLTClient->KillSound(pNodeControl->hLipSyncSound); pNodeControl->hLipSyncSound = LTNULL; if (pNodeControl->bShowingSubtitles) { g_pInterfaceMgr->ClearSubtitle(); } pNodeControl->pSixteenBitBuffer = LTNULL; pNodeControl->pEightBitBuffer = LTNULL; pNodeControl->bValid = LTFALSE; return; } // // Process the current sound data (average over sound amplitude). // LTFLOAT fAverage = 0.0f; // this will hold the average, normalized from 0.0f to 1.0f. // Get the sound buffer. if( !pNodeControl->pSixteenBitBuffer && !pNodeControl->pEightBitBuffer ) { uint32 dwChannels = 0; g_pLTClient->GetSoundData(pNodeControl->hLipSyncSound, pNodeControl->pSixteenBitBuffer, pNodeControl->pEightBitBuffer, &pNodeControl->dwSamplesPerSecond, &dwChannels); ASSERT( dwChannels == 1); // If you want to use multi-channel sounds (why would you?), you'll need to // to account for the interleaving of channels in the following code. } ASSERT( pNodeControl->pSixteenBitBuffer || pNodeControl->pEightBitBuffer ); // Average over the data. We do an average of the data from the current point // being played to 1/g_vtLipSyncFreq.GetFloat() seconds ahead of that point. uint32 dwOffset = 0; uint32 dwSize = 0; if( LT_OK == g_pLTClient->GetSoundOffset(pNodeControl->hLipSyncSound, &dwOffset, &dwSize) ) { // Determine the end of the data we wish to average over. const uint32 dwDivisor = uint32(g_vtLipSyncFreq.GetFloat()); uint32 dwOffsetEnd = dwOffset + pNodeControl->dwSamplesPerSecond/dwDivisor; if( dwOffsetEnd > dwSize ) dwOffsetEnd = dwSize; // Accumulate the the amplitudes for the average. uint32 dwMaxAmplitude = 0; uint32 dwNumSamples = 0; uint32 dwAccum = 0; if( pNodeControl->pSixteenBitBuffer ) { for( int16 * pIterator = pNodeControl->pSixteenBitBuffer + dwOffset; pIterator < pNodeControl->pSixteenBitBuffer + dwOffsetEnd; ++pIterator) { dwAccum += abs(*pIterator); ++dwNumSamples; } dwMaxAmplitude = 65536/2; #ifdef GRAPH_LIPSYNC_SOUND g_GraphPoints.RecordData(pNodeControl->pSixteenBitBuffer,dwSize,dwOffset); #endif } else if( pNodeControl->pEightBitBuffer ) { for( int8 * pIterator = pNodeControl->pEightBitBuffer + dwOffset; pIterator < pNodeControl->pEightBitBuffer + dwOffsetEnd; ++pIterator) { dwAccum += abs(*pIterator); ++dwNumSamples; } dwMaxAmplitude = 256/2; #ifdef GRAPH_LIPSYNC_SOUND g_GraphPoints.RecordData(pNodeControl->pEightBitBuffer,dwSize,dwOffset); #endif } // And find the average! if( dwNumSamples > 0 ) fAverage = LTFLOAT(dwAccum) / LTFLOAT(dwNumSamples) / LTFLOAT(dwMaxAmplitude); } //if( LT_OK == g_pLTClient->GetSoundOffset(pNodeControl->hLipSyncSound, &dwOffset, &dwSize) ) // // Do the rotation. // ILTMath *pMathLT = g_pLTClient->GetMathLT(); LTRotation rRot; rRot.Init(); LTVector vAxis(0.0f, 0.0f, 1.0f); LTFLOAT fMaxRot = MATH_DEGREES_TO_RADIANS(g_vtLipSyncMaxRot.GetFloat()); // Calculate the rotation. m_fCurLipSyncRot = fAverage*fMaxRot; pMathLT->RotateAroundAxis(rRot, vAxis, -m_fCurLipSyncRot); // Create a rotation matrix and apply it to the current offset matrix LTMatrix m1; pMathLT->SetupRotationMatrix(m1, rRot); m_aNodes[pNodeControl->eModelNode].matTransform = m_aNodes[pNodeControl->eModelNode].matTransform * m1; }
void SecurityCamera::SetupDisabledState() { if (m_eState == eStateDisabled || m_hDisablerModel) return; uint32 dwUserFlags = g_pLTServer->GetObjectUserFlags(m_hObject); g_pLTServer->SetObjectUserFlags(m_hObject, dwUserFlags & ~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; SAFE_STRCPY(theStruct.m_Filename, "Guns\\Models_HH\\Cameradis_hh.abc"); SAFE_STRCPY(theStruct.m_SkinName, "Guns\\Skins_HH\\Cameradis_hh.dtx"); 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; // Attach the model to the the camera... LTVector vOffset; VEC_INIT(vOffset); LTRotation rOffset; rOffset.Init(); 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, "DownUp"); if (hAni) { g_pLTServer->SetModelLooping(m_hDisablerModel, LTFALSE); g_pLTServer->SetModelAnimation(m_hDisablerModel, hAni); } // Play the activate sound... char* pSound = "Guns\\Snd\\Cam_dis\\activate.wav"; g_pServerSoundMgr->PlaySoundFromPos(m_vPos, pSound, 500.0f, SOUNDPRIORITY_MISC_LOW); // Camera is now disabled... m_bDisabled = LTTRUE; }
void CLaserBeam::Update(LTVector vBeamStartPos, LTRotation* pRDirRot, LTBOOL b3rdPerson, LTBOOL bDetect) { if (!m_bOn) return; // Calculate beam position... HOBJECT hCamera = g_pGameClientShell->GetCamera(); if (!hCamera) return; HLOCALOBJ hPlayerObj = g_pLTClient->GetClientObject(); if (!hPlayerObj) return; HOBJECT hFilterList[] = {hPlayerObj, g_pGameClientShell->GetMoveMgr()->GetObject(), LTNULL}; IntersectQuery qInfo; IntersectInfo iInfo; LTVector vPos(0, 0, 0); LTRotation rRot; rRot.Init(); LTVector vU, vR, vF; if (pRDirRot && b3rdPerson) { vPos = vBeamStartPos; g_pLTClient->GetRotationVectors(pRDirRot, &vU, &vR, &vF); } else { g_pLTClient->GetObjectRotation(hCamera, &rRot); g_pLTClient->GetObjectPos(hCamera, &vPos); g_pLTClient->GetRotationVectors(&rRot, &vU, &vR, &vF); if (g_cvarLaserBeamDebug.GetFloat() == 0.0f) { vBeamStartPos += vPos; } else if (g_cvarLaserBeamDebug.GetFloat() == 1.0f) { vBeamStartPos = vPos; } else { g_pLTClient->GetRotationVectors(pRDirRot, &vU, &vR, &vF); vBeamStartPos = vBeamStartPos; } } LTVector vEndPos = vPos + (vF * 10000.0f); qInfo.m_From = vPos; qInfo.m_To = vEndPos; qInfo.m_Flags = INTERSECT_OBJECTS | IGNORE_NONSOLID; qInfo.m_FilterFn = ObjListFilterFn; qInfo.m_pUserData = hFilterList; if (g_pLTClient->IntersectSegment(&qInfo, &iInfo)) { vEndPos = iInfo.m_Point; } // Show the light beam... LTVector vColor = LTVector(GetRandom(235.0f, 255.0f), GetRandom(35.0f, 55.0f), GetRandom(35.0f, 55.0f));; LTFLOAT fAlpha = g_cvarLaserBeamAlpha.GetFloat(); if (iInfo.m_hObject && bDetect) { uint32 dwUsrFlgs = 0; g_pLTClient->GetObjectUserFlags(iInfo.m_hObject, &dwUsrFlgs); if (dwUsrFlgs & USRFLG_CHARACTER) { fAlpha = 0.95f; vColor.Init(GetRandom(35.0f, 55.0f), GetRandom(235.0f, 255.0f), GetRandom(35.0f, 55.0f));; } } LTFLOAT fWidth = g_cvarLaserBeamThickness.GetFloat(); fWidth = b3rdPerson ? fWidth*2.0f : fWidth; vBeamStartPos += (vF * g_cvarLaserBeamFOffset.GetFloat()); vBeamStartPos += (vR * g_cvarLaserBeamROffset.GetFloat()); vBeamStartPos += (vU * g_cvarLaserBeamUOffset.GetFloat()); PLFXCREATESTRUCT pls; if (g_cvarLaserBeamDebug.GetFloat() >= 0.0f) { // g_pLTClient->CPrint("StartPos = %.2f, %.2f, %.2f", VEC_EXPAND(vBeamStartPos)); // g_pLTClient->CPrint("EndPos = %.2f, %.2f, %.2f", VEC_EXPAND(vEndPos)); } pls.vStartPos = vBeamStartPos; pls.vEndPos = vEndPos; pls.vInnerColorStart = vColor; pls.vInnerColorEnd = pls.vInnerColorStart; pls.vOuterColorStart = LTVector(0, 0, 0); pls.vOuterColorEnd = LTVector(0, 0, 0); pls.fAlphaStart = fAlpha; pls.fAlphaEnd = fAlpha; pls.fMinWidth = 0; pls.fMaxWidth = fWidth; pls.fMinDistMult = 1.0f; pls.fMaxDistMult = 1.0f; pls.fLifeTime = 1.0f; pls.fAlphaLifeTime = 1.0f; pls.fPerturb = 0.0f; pls.bAdditive = LTTRUE; pls.bAlignFlat = b3rdPerson ? LTFALSE : LTTRUE; pls.nWidthStyle = PLWS_CONSTANT; pls.nNumSegments = (int)g_cvarLaserBeamNumSegments.GetFloat(); if (m_LightBeam.HasBeenDrawn()) { // Keep the light beam in the vis list... m_LightBeam.SetPos(vBeamStartPos); // Hide the beam in portals if 1st person...Also set flag really // close to true... uint32 dwFlags2, dwFlags; dwFlags = m_LightBeam.GetFlags(); dwFlags2 = m_LightBeam.GetFlags2(); if (b3rdPerson) { dwFlags &= ~FLAG_REALLYCLOSE; dwFlags2 &= ~FLAG2_PORTALINVISIBLE; } else { if (g_cvarLaserBeamDebug.GetFloat() > 1.0f) { dwFlags |= FLAG_REALLYCLOSE; pls.bUseObjectRotation = LTTRUE; } dwFlags2 |= FLAG2_PORTALINVISIBLE; } m_LightBeam.SetFlags(dwFlags); m_LightBeam.SetFlags2(dwFlags2); m_LightBeam.ReInit(&pls); } else { m_LightBeam.Init(&pls); m_LightBeam.CreateObject(g_pLTClient); } m_LightBeam.Update(); }