bool CCreateRayFX::Update( float tmFrameTime ) { //track our performance CTimedSystemBlock TimingBlock(g_tsClientFXCreateRayFX); //update our base object BaseUpdate(tmFrameTime); //we only want to create the effect as we become active if(IsInitialFrame() && (GetProps()->m_nNumToCreate > 0)) { //determine the object position and orientation of our object LTVector vObjPos; LTRotation rObjRot; GetCurrentTransform(GetUnitLifetime(), vObjPos, rObjRot); //handle two special pipelines to gain performance when there is no scattering if(MATH_RADIANS_TO_DEGREES(GetProps()->m_fRandomCone) < 1.0f) { LTRigidTransform tHitTrans; HOBJECT hHitObj; //no scattering, just do a single intersection for all effects if(DetermineIntersection(vObjPos, rObjRot.Forward(), hHitObj, tHitTrans)) { //and now generate all of our effects for(uint32 nCurrEffect = 0; nCurrEffect < GetProps()->m_nNumToCreate; nCurrEffect++) { CLIENTFX_CREATESTRUCT CreateStruct("", GetProps()->m_nFXFlags, hHitObj, tHitTrans); CBaseCreateFX::CreateEffect(CreateStruct); } } } else { //we need to scatter //extract our vectors from the orientation LTVector vObjRight, vObjUp, vObjForward; rObjRot.GetVectors(vObjRight, vObjUp, vObjForward); //and now generate all of our effects for(uint32 nCurrEffect = 0; nCurrEffect < GetProps()->m_nNumToCreate; nCurrEffect++) { LTRigidTransform tHitTrans; HOBJECT hHitObj; //now build up the forward within a specified cone //first off spin it randomly around the forward float fPlaneAngle = GetRandom(0.0f, MATH_CIRCLE); LTVector vPlaneVector = vObjRight * cosf(fPlaneAngle) + vObjUp * sinf(fPlaneAngle); //now tilt it away from the forward vector float fTiltPercent = powf(GetRandom(0.0f, 1.0f), GetProps()->m_fCenterBias); float fTiltAngle = fTiltPercent * GetProps()->m_fRandomCone; LTVector vRandomForward = vObjForward * cosf(fTiltAngle) + vPlaneVector * sinf(fTiltAngle); if(DetermineIntersection(vObjPos, vRandomForward, hHitObj, tHitTrans)) { CLIENTFX_CREATESTRUCT CreateStruct("", GetProps()->m_nFXFlags, hHitObj, tHitTrans); CBaseCreateFX::CreateEffect(CreateStruct); } } } } //we always return false because we always want to be placed into a shutting down state since //we just emit and then do nothing return false; }