static void handle_T0(FmmvHandle *FMMV, Box *box, int T0[][9], _FLOAT_ *X, _FLOAT_ *X1, _FLOAT_ *X2) { int i; _FLOAT_ *D_X2X = FMMV->D_X2X; int s_exp = FMMV->s_exp; int s_exp2 = FMMV->s_exp/2; for (i=0; i<8; i++) { if (isSource(box->child[T0[i][0]])) { if (T0[i][2]) { /* conjugate */ VEC_MUL_CJ(s_exp2, D_X2X + s_exp*T0[i][1], X1 + s_exp*T0[i][0], X + s_exp*T0[i][3]); } else { VEC_MUL_C(s_exp2, D_X2X + s_exp*T0[i][1], X1 + s_exp*T0[i][0], X + s_exp*T0[i][3]); } VEC_ADD(s_exp, X + s_exp*T0[i][3], X + s_exp*T0[i][4], X + s_exp*T0[i][4]); if (T0[i][6]) { /* conjugate */ VEC_MUL_CJ(s_exp2, D_X2X + s_exp*T0[i][5], X2 + s_exp*T0[i][0], X + s_exp*T0[i][7]); } else { VEC_MUL_C(s_exp2, D_X2X + s_exp*T0[i][5], X2 + s_exp*T0[i][0], X + s_exp*T0[i][7]); } VEC_ADD(s_exp, X + s_exp*T0[i][7], X + s_exp*T0[i][8], X + s_exp*T0[i][8]); } } VEC_ADD(s_exp, X + s_exp*XU_D, X + s_exp*XU_all, X + s_exp*XU_all); VEC_ADD(s_exp, X + s_exp*XD_D, X + s_exp*XD_all, X + s_exp*XD_all); }
/* ** All the three given vectors span only a 2D space, and this finds ** the normal to that plane. Simply sums up all the pair-wise ** cross-products to get a good estimate. Trick is getting the cross ** products to line up before summing. */ void nullspace1(double ret[3], const double r0[3], const double r1[3], const double r2[3]) { double crs[3]; /* ret = r0 x r1 */ VEC_CROSS(ret, r0, r1); /* crs = r1 x r2 */ VEC_CROSS(crs, r1, r2); /* ret += crs or ret -= crs; whichever makes ret longer */ if (VEC_DOT(ret, crs) > 0) { VEC_ADD(ret, crs); } else { VEC_SUB(ret, crs); } /* crs = r0 x r2 */ VEC_CROSS(crs, r0, r2); /* ret += crs or ret -= crs; whichever makes ret longer */ if (VEC_DOT(ret, crs) > 0) { VEC_ADD(ret, crs); } else { VEC_SUB(ret, crs); } return; }
DBOOL CShellCasingFX::CreateObject(CClientDE *pClientDE) { if (!CSpecialFX::CreateObject(pClientDE)) return DFALSE; char* pModelName = DNULL; char* pSkinName = DNULL; if (!GetFileNames(&pModelName, &pSkinName)) return DFALSE; if (!pModelName || !pSkinName) return DFALSE; // Setup the shell... ObjectCreateStruct createStruct; INIT_OBJECTCREATESTRUCT(createStruct); createStruct.m_ObjectType = OT_MODEL; createStruct.m_Flags = 0; _mbscpy((unsigned char*)createStruct.m_Filename, (const unsigned char*)pModelName); _mbscpy((unsigned char*)createStruct.m_SkinName, (const unsigned char*)pSkinName); VEC_COPY(createStruct.m_Pos, m_vStartPos); ROT_COPY(createStruct.m_Rotation, m_rRot); m_hObject = pClientDE->CreateObject(&createStruct); if (!m_hObject) return DFALSE; m_pClientDE->SetObjectScale(m_hObject, &m_vScale); DVector vU, vR, vF; pClientDE->GetRotationVectors(&m_rRot, &vU, &vR, &vF); DVector vVel; if(m_bLeftHanded) VEC_NEGATE(vR, vR); DFLOAT fUpVel = GetRandom(60.0f, 90.0f); VEC_MULSCALAR(vU, vU, fUpVel); DFLOAT fRightVel = GetRandom(50.0f, 70.0f); VEC_MULSCALAR(vR, vR, fRightVel); DFLOAT fForwardVel = GetRandom(10.0f, 25.0f); VEC_MULSCALAR(vF, vF, fForwardVel); VEC_ADD(vVel, vU, vR); VEC_ADD(vVel, vVel, vF); InitMovingObject(&m_movingObj, &m_vStartPos, &vVel);; m_movingObj.m_PhysicsFlags |= MO_HALFGRAVITY; m_fExpireTime = 20.0f + m_pClientDE->GetTime(); // Set the pitch velocity m_fPitchVel = GetRandom(-MATH_CIRCLE * 2, MATH_CIRCLE * 2); m_fYawVel = GetRandom(-MATH_CIRCLE * 2, MATH_CIRCLE * 2); m_fPitch = m_fYaw = 0.0f; return DTRUE; }
DBOOL UpdateMovingObject(PhysicsState *pUserState, MovingObject *pObject, DVector *pNewPos) { if (!pObject || !pNewPos) return DFALSE; PhysicsState* pState = pUserState ? pUserState : GetCurPhysicsState(pObject); if (!pState) return DFALSE; DVector vTemp, velocityDelta, posDelta; if(pObject->m_PhysicsFlags & MO_RESTING) return DFALSE; // Prevent tiny movements. if(VEC_MAGSQR(pObject->m_Acceleration) < 0.01f) { VEC_INIT(pObject->m_Acceleration); } if(VEC_MAGSQR(pObject->m_Velocity) < 0.01f) { VEC_INIT(pObject->m_Velocity); } // velocityDelta = ( acceleration + accelDelta * 0.5 ) * dt; VEC_INIT(vTemp); if (!(pObject->m_PhysicsFlags & MO_NOGRAVITY)) { DFLOAT fScale = 0.5f; if (pObject->m_PhysicsFlags & MO_HALFGRAVITY) { fScale = 0.20f; } VEC_MULSCALAR(vTemp, pState->m_GravityAccel, fScale); } VEC_ADD(vTemp, vTemp, pObject->m_Acceleration); VEC_MULSCALAR(velocityDelta, vTemp, pState->m_TimeStep); // Apply the velocity to the position (p = p + vt + 0.5a(t^2)). VEC_MULSCALAR(posDelta, pObject->m_Acceleration, pState->m_TimeStepIntegral); VEC_ADDSCALED(posDelta, posDelta, pObject->m_Velocity, pState->m_TimeStep); // Add the final velocity to the new velocity. VEC_ADD(pObject->m_Velocity, pObject->m_Velocity, velocityDelta); if(!pNewPos) pNewPos = &pObject->m_Pos; VEC_ADD(*pNewPos, pObject->m_Pos, posDelta); // Zero out the acceleration. VEC_INIT(pObject->m_Acceleration); return DTRUE; }
LTBOOL ScaleSprite::Update() { if (m_bStartOn) { g_pCommonLT->SetObjectFlags(m_hObject, OFT_User, USRFLG_VISIBLE, USRFLG_VISIBLE); g_pCommonLT->SetObjectFlags(m_hObject, OFT_Flags, FLAG_VISIBLE, FLAG_VISIBLE); } SetNextUpdate(UPDATE_NEVER); // BUG - This isn't quite right. Sometimes this works (flipping the sprite) // other times the sprite shouldn't be flipped...Not sure what the bug is. // For some reason the sprites are sometimes backwards...Get the rotation // so we can flip it... LTRotation rRot; LTVector vPos, vDir, vU, vR, vF; g_pLTServer->GetObjectPos(m_hObject, &vPos); g_pLTServer->GetObjectRotation(m_hObject, &rRot); vU = rRot.Up(); vR = rRot.Right(); vF = rRot.Forward(); if (m_bFlushWithWorld) { // Align the sprite to the surface directly behind the sprite // (i.e., opposite the forward vector)... VEC_NORM(vF); VEC_MULSCALAR(vDir, vF, -1.0f); // Determine where on the surface to place the sprite... IntersectInfo iInfo; IntersectQuery qInfo; VEC_COPY(qInfo.m_From, vPos); VEC_COPY(qInfo.m_Direction, vDir); qInfo.m_Flags = IGNORE_NONSOLID | INTERSECT_OBJECTS | INTERSECT_HPOLY; qInfo.m_FilterFn = LTNULL; if (g_pLTServer->CastRay(&qInfo, &iInfo)) { LTVector vTemp; VEC_COPY(vPos, iInfo.m_Point); VEC_COPY(vDir, iInfo.m_Plane.m_Normal); // Place the sprite just above the surface... VEC_MULSCALAR(vTemp, vDir, 1.0f); VEC_ADD(vPos, vPos, vTemp); g_pLTServer->SetObjectPos(m_hObject, &vPos); } } return LTTRUE; }
DBOOL CBaseParticleSystemFX::Update() { if(!m_hObject || !m_pClientDE) return DFALSE; // See if we should rotate this bad-boy... if (m_vRotVel.x != 0.0f || m_vRotVel.y != 0.0f || m_vRotVel.z != 0.0f) { DFLOAT fDelta = m_pClientDE->GetFrameTime(); DRotation rRot; m_pClientDE->GetObjectRotation(m_hObject, &rRot); DVector vTemp; VEC_MULSCALAR(vTemp, m_vRotVel, fDelta); VEC_ADD(m_vRotAmount, m_vRotAmount, vTemp); if (m_vRotVel.x != 0.0f) m_pClientDE->EulerRotateX(&rRot, m_vRotAmount.x); if (m_vRotVel.y != 0.0f) m_pClientDE->EulerRotateY(&rRot, m_vRotAmount.y); if (m_vRotVel.z != 0.0f) m_pClientDE->EulerRotateZ(&rRot, m_vRotAmount.z); m_pClientDE->SetObjectRotation(m_hObject, &rRot); } return DTRUE; }
bool test_vector() { Vector init; bool test_result = true; // true == passed init.v[0] = 0.0f; VEC_INIT(init); CHECK(init.v[0] == 0.0f, "test_vector: INIT failed\n"); CHECK(init.v[1] == 0.0f, "test_vector: INIT failed\n"); CHECK(init.v[2] == 0.0f, "test_vector: INIT failed\n"); CHECK(init.v[3] == 0.0f, "test_vector: INIT failed\n"); CHECK(init.vec.x == 0.0f, "test_vector: INIT failed\n"); CHECK(init.vec.y == 0.0f, "test_vector: INIT failed\n"); CHECK(init.vec.z == 0.0f, "test_vector: INIT failed\n"); CHECK(init.vec.w == 0.0f, "test_vector: INIT failed\n"); CHECK(init.col.r == 0.0f, "test_vector: INIT failed\n"); CHECK(init.col.g == 0.0f, "test_vector: INIT failed\n"); CHECK(init.col.b == 0.0f, "test_vector: INIT failed\n"); CHECK(init.col.a == 0.0f, "test_vector: INIT failed\n"); init.v[0] = 1.0f; init.v[1] = 2.0f; init.v[2] = 3.0f; init.v[3] = 4.0f; CHECK(init.vec.x == 1.0f, "test_vector: union test failed\n"); CHECK(init.vec.y == 2.0f, "test_vector: union test failed\n"); CHECK(init.vec.z == 3.0f, "test_vector: union test failed\n"); CHECK(init.vec.w == 4.0f, "test_vector: union test failed\n"); CHECK(init.col.r == 1.0f, "test_vector: union test failed\n"); CHECK(init.col.g == 2.0f, "test_vector: union test failed\n"); CHECK(init.col.b == 3.0f, "test_vector: union test failed\n"); CHECK(init.col.a == 4.0f, "test_vector: union test failed\n"); VEC_ASSIGN(init, 5.0f, 6.0f, 7.0f, 8.0f); CHECK(init.v[0] == 5.0f, "test_vector: VEC_ASSIGN failed\n"); CHECK(init.v[1] == 6.0f, "test_vector: VEC_ASSIGN failed\n"); CHECK(init.v[2] == 7.0f, "test_vector: VEC_ASSIGN failed\n"); CHECK(init.v[3] == 8.0f, "test_vector: VEC_ASSIGN failed\n"); Vector second; VEC_ASSIGN(second, 9.0f, 10.0f, 11.0f, 12.0f); Vector result; VEC_ADD(result, init, second); CHECK(result.v[0] == 14.0f, "test_vector: VEC_ADD failed\n"); CHECK(result.v[1] == 16.0f, "test_vector: VEC_ADD failed\n"); CHECK(result.v[2] == 18.0f, "test_vector: VEC_ADD failed\n"); CHECK(result.v[3] == 20.0f, "test_vector: VEC_ADD failed\n"); return test_result; }
DVector CPlayerCamera::FindFirstPersonCameraPosition(DVector vPos, DVector vF) { DVector vTemp; VEC_MULSCALAR(vTemp, vF, m_TargetFirstPersonOffset.x); VEC_ADD(vPos, vPos, vTemp); vPos.y += m_TargetFirstPersonOffset.y; return vPos; }
void BugAI::MC_Run() { if (m_bAnimating == DFALSE || m_nCurMetacmd != MC_RUN) { DBOOL bRet = DFALSE; m_fTimeStart = m_pServerDE->GetTime(); Move(m_MoveObj.GetForwardVector(),m_fRunSpeed); m_bAnimating = DTRUE; m_nCurMetacmd = MC_RUN; } else { //Check for obstruction; otherwise continue on if(CheckObstructed(m_MoveObj.GetForwardVector(), m_fRunSpeed)) { IntersectQuery IQuery; IntersectInfo ii; IQuery.m_Flags = INTERSECT_OBJECTS; IQuery.m_FilterFn = DNULL; DVector vTemp; VEC_MULSCALAR(vTemp,m_MoveObj.GetForwardVector(),m_fRunSpeed); VEC_COPY(IQuery.m_From,m_MoveObj.GetPos()); VEC_ADD(IQuery.m_To,IQuery.m_From,vTemp); if(m_pServerDE->IntersectSegment(&IQuery, &ii)) { //climb the object DRotation rRot; m_pServerDE->AlignRotation(&rRot,&m_MoveObj.GetUpVector(),&ii.m_Plane.m_Normal); m_pServerDE->SetObjectRotation(m_hObject,&rRot); m_bAnimating = DFALSE; Metacmd++; return; } } Move(m_MoveObj.GetForwardVector(),m_fRunSpeed); //Are we done running? if(m_pServerDE->GetModelPlaybackState(m_hObject) & MS_PLAYDONE) { m_bAnimating = DFALSE; Metacmd++; } } return; }
/* ** All vectors are in the same 1D space, we have to find two ** mutually vectors perpendicular to that span */ void nullspace2(double reta[3], double retb[3], const double r0[3], const double r1[3], const double r2[3]) { double sqr[3], sum[3]; int idx; VEC_COPY(sum, r0); if (VEC_DOT(sum, r1) > 0) { VEC_ADD(sum, r1); } else { VEC_SUB(sum, r1); } if (VEC_DOT(sum, r2) > 0) { VEC_ADD(sum, r2); } else { VEC_SUB(sum, r2); } /* find largest component, to get most stable expression for a perpendicular vector */ sqr[0] = sum[0]*sum[0]; sqr[1] = sum[1]*sum[1]; sqr[2] = sum[2]*sum[2]; idx = 0; if (sqr[0] < sqr[1]) idx = 1; if (sqr[idx] < sqr[2]) idx = 2; /* reta will be perpendicular to sum */ if (0 == idx) { VEC_SET(reta, sum[1] - sum[2], -sum[0], sum[0]); } else if (1 == idx) { VEC_SET(reta, -sum[1], sum[0] - sum[2], sum[1]); } else { VEC_SET(reta, -sum[2], sum[2], sum[0] - sum[1]); } /* and now retb will be perpendicular to both reta and sum */ VEC_CROSS(retb, reta, sum); return; }
void CHandWeaponModel::Drop() { CServerDE* pServerDE = GetServerDE(); if (!pServerDE) return; m_bDropped = DTRUE; DVector vF, vR, vU; DRotation rRot; // Set some minimum dims, and make sure x and z are the same. DVector vDims; pServerDE->GetModelAnimUserDims(m_hObject, &vDims, pServerDE->GetModelAnimation(m_hObject)); if (vDims.x < 10.0f) vDims.x = 10.0f; if (vDims.x > vDims.z) vDims.z = vDims.x; else vDims.x = vDims.z; // g_pServerDE->BPrint("Setting PU dims %f,%f,%f", VEC_EXPAND(vDims)); if (pServerDE->SetObjectDims2(m_hObject, &vDims) == DE_ERROR) // Get vectors to set a velocity pServerDE->GetObjectRotation(m_hObject, &rRot); pServerDE->GetRotationVectors(&rRot, &vU, &vR, &vF); // Set some forward and upward velocity VEC_ADD(vF, vF, vU); VEC_MULSCALAR(vF, vF, 150.0f); pServerDE->SetVelocity(m_hObject, &vF); // Make it visible DDWORD dwFlags = pServerDE->GetObjectFlags(m_hObject); pServerDE->SetObjectFlags(m_hObject, dwFlags | FLAG_NOSLIDING | FLAG_VISIBLE | FLAG_GRAVITY | FLAG_REMOVEIFOUTSIDE); // Show the model on the client now /* if(m_dwClientID) { HMESSAGEWRITE hMsg = pServerDE->StartSpecialEffectMessage(this); pServerDE->WriteToMessageByte(hMsg, SFX_WEAPONHANDMODEL_ID); pServerDE->WriteToMessageDWord(hMsg, m_dwClientID); pServerDE->WriteToMessageByte(hMsg, (m_bLeftHand << 1) | DTRUE); pServerDE->EndMessage2(hMsg, MESSAGE_GUARANTEED); } */ // Set next update for 1 second to spawn a powerup pServerDE->SetNextUpdate( m_hObject, 1.0f); }
static size_t ve_anchors_add(br_x509_certificate *xcs, size_t num, anchor_list *anchors) { br_x509_trust_anchor ta; size_t u; for (u = 0; u < num; u++) { if (certificate_to_trust_anchor_inner(&ta, &xcs[u]) < 0) { break; } VEC_ADD(*anchors, ta); } return (u); }
void CClientExplosionSFX::Setup(DVector *vPos, DVector *vNormal, DFLOAT fOffset) { VEC_COPY(m_vPos, *vPos); VEC_COPY(m_vNormal, *vNormal); m_fOffset = fOffset; if(m_fOffset) { DVector temp; VEC_NORM(m_vNormal); VEC_MULSCALAR(temp, m_vNormal, m_fOffset); VEC_ADD(m_vPos, m_vPos, temp); } }
void CDestructable::ApplyDamagePhysics(DFLOAT fDamage, DVector *pvDir) { CServerDE* pServerDE = BaseClass::GetServerDE(); if (!pServerDE || !m_hObject || !pvDir) return; // Don't apply damage physics if the object is a trapped character (Andy 2/22/99) if(IsBaseCharacter(m_hObject)) { CBaseCharacter *pObj = (CBaseCharacter*)pServerDE->HandleToObject(m_hObject); if(pObj->IsTrapped()) return; } if (VEC_MAGSQR(*pvDir) < 0.01) return; DVector vTemp, vVel; pServerDE->GetVelocity(m_hObject, &vVel); VEC_COPY(vTemp, *pvDir); VEC_NORM(vTemp); if (m_fMass <= 0) m_fMass = 1; DFLOAT fMultiplier = (fDamage * PA_DAMAGE_VEL_MUTLIPLIER) / m_fMass; VEC_MULSCALAR(vTemp, vTemp, fMultiplier); VEC_ADD(vVel, vTemp, vVel); // Accumulate damage velocity for player objects to send to the client.. if (IsPlayer(m_hObject)) { VEC_ADD(m_vAddVelocity, m_vAddVelocity, vTemp); m_bAddVelocity = DTRUE; } pServerDE->SetVelocity(m_hObject, &vVel); }
GEO * file_geo_sphere (BYTE Type, FILE *File) { GEO_SPHERE *Geo; VECTOR Vector; INIT_MEM (Geo, 1, GEO_SPHERE); Geo->Type = Type; GET_VECTOR (Geo->Point); GET_REAL (Geo->Radius); Vector.x = Vector.y = Vector.z = Geo->Radius; VEC_SUB (Geo->Min, Geo->Point, Vector); VEC_ADD (Geo->Max, Geo->Point, Vector); return ((GEO *) Geo); }
LTBOOL CParticleTrailSegmentFX::Update() { if (!m_hObject || !m_pClientDE) return LTFALSE; if (!CBaseParticleSystemFX::Update()) return LTFALSE; CGameSettings* pSettings = g_pInterfaceMgr->GetSettings(); if (!pSettings) return LTFALSE; uint8 nDetailLevel = pSettings->SpecialFXSetting(); LTFLOAT fTime = m_pClientDE->GetTime(); if (m_bFirstUpdate) { if (!m_hServerObject) return LTFALSE; m_bFirstUpdate = LTFALSE; m_fStartTime = fTime; m_fLastTime = fTime; // Where is the server (moving) object... LTVector vPos, vTemp; m_pClientDE->GetObjectPos(m_hServerObject, &vPos); // Current position is relative to the particle system's postion (i.e., // each puff of Particle is some distance away from the particle system's /// position)... m_pClientDE->GetObjectPos(m_hObject, &vTemp); VEC_SUB(vPos, vPos, vTemp); VEC_COPY(m_vLastPos, vPos); } // Check to see if we should just wait for last Particle puff to go away... if (m_bWantRemove || (fTime > m_fStartTime + m_fFadeTime)) { if (fTime > m_fLastTime + m_fLifeTime) { return LTFALSE; } LTFLOAT fScale = (m_fLifeTime - (fTime - m_fLastTime)) / m_fLifeTime; LTFLOAT r, g, b, a; m_pClientDE->GetObjectColor(m_hObject, &r, &g, &b, &a); m_pClientDE->SetObjectColor(m_hObject, r, g, b, fScale); return LTTRUE; } // See if it is time to create a new Particle puff... if ((fTime > m_fLastTime + m_fOffsetTime) && m_hServerObject) { LTVector vCurPos, vPos, vDelta, vTemp, vDriftVel, vColor; // Calculate Particle puff position... // Where is the server (moving) object... m_pClientDE->GetObjectPos(m_hServerObject, &vCurPos); // Current position is relative to the particle system's postion (i.e., // each puff of Particle is some distance away from the particle system's /// position)... m_pClientDE->GetObjectPos(m_hObject, &vTemp); VEC_SUB(vCurPos, vCurPos, vTemp); // How long has it been since the last Particle puff? LTFLOAT fTimeOffset = fTime - m_fLastTime; // What is the range of colors? LTFLOAT fRange = m_vColor2.x - m_vColor1.x; // Fill the distance between the last projectile position, and it's // current position with Particle puffs... int nNumSteps = (m_fLastTime > 0) ? (((m_nType & PT_BLOOD) || (m_nType & PT_GIBSMOKE)) ? 20 : 5): 1; if (nDetailLevel != RS_HIGH) { nNumSteps /= 2; } VEC_SUB(vTemp, vCurPos, m_vLastPos); VEC_MULSCALAR(vDelta, vTemp, 1.0f/float(nNumSteps)); VEC_COPY(vPos, m_vLastPos); LTFLOAT fCurLifeTime = 10.0f; if (nDetailLevel == RS_HIGH) { fCurLifeTime /= 2; } LTFLOAT fLifeTimeOffset = fTimeOffset / float(nNumSteps); LTFLOAT fOffset = 0.5f; int nNumPerPuff = GetNumParticles(m_nNumPerPuff); for (int i=0; i < nNumSteps; i++) { // Build the individual Particle puffs... for (int j=0; j < nNumPerPuff; j++) { VEC_COPY(vTemp, vPos); if (m_bIgnoreWind) { VEC_SET(vDriftVel, GetRandom(-m_vDriftOffset.x*2.0f, -m_vDriftOffset.x), GetRandom(5.0f, 6.0f), GetRandom(-m_vDriftOffset.z, m_vDriftOffset.z)); } else { VEC_SET(vDriftVel, g_vWorldWindVel.x + GetRandom(-m_vDriftOffset.x*2.0f, -m_vDriftOffset.x), g_vWorldWindVel.y + GetRandom(5.0f, 6.0f), g_vWorldWindVel.z + GetRandom(-m_vDriftOffset.z, m_vDriftOffset.z)); } vTemp.x += GetRandom(-fOffset, fOffset); vTemp.y += GetRandom(-fOffset, fOffset); vTemp.z += GetRandom(-fOffset, fOffset); GetRandomColorInRange(vColor); m_pClientDE->AddParticle(m_hObject, &vTemp, &vDriftVel, &vColor, fCurLifeTime); } VEC_ADD(vPos, vPos, vDelta); fCurLifeTime += fLifeTimeOffset; } m_fLastTime = fTime; VEC_COPY(m_vLastPos, vCurPos); } return LTTRUE; }
bool test_list() { bool test_result = true; // true == passed DEFINE_LIST(int, int_list); DEFINE_LIST(Vector, vec_list); int_list test_int; vec_list test_vec; CREATE_LIST(test_int, int, 5); CREATE_LIST(test_vec, Vector, 5); ADD_LIST(test_int, 5); CHECK(test_int.l[0] == 5, "test_int vector ADD_LIST failed"); CHECK(test_int.cur_size = 1, "test_int vector ADD_LIST failed"); ADD_LIST(test_int, 6); ADD_LIST(test_int, 7); ADD_LIST(test_int, 8); ADD_LIST(test_int, 9); ADD_LIST(test_int, 10); ADD_LIST(test_int, 11); CHECK(test_int.l[0] == 5, "test_int vector ADD_LIST failed"); CHECK(test_int.l[1] == 6, "test_int vector ADD_LIST failed"); CHECK(test_int.l[2] == 7, "test_int vector ADD_LIST failed"); CHECK(test_int.l[3] == 8, "test_int vector ADD_LIST failed"); CHECK(test_int.l[4] == 9, "test_int vector ADD_LIST failed"); CHECK(test_int.l[5] == 10, "test_int vector ADD_LIST failed"); CHECK(test_int.l[6] == 11, "test_int vector ADD_LIST failed"); CHECK(test_int.cur_size == 7, "test_int vector ADD_LIST failed"); CHECK(test_int.max_size == 10, "test_int vector ADD_LIST failed"); FREE_LIST(test_int); Vector val; val.v[0] = val.v[1] = val.v[2] = val.v[3] = 10.0f; ADD_LIST(test_vec, val); CHECK(test_vec.l[0].v[0] == 10.0f, "test_vec vector ADD_LIST failed"); CHECK(test_vec.l[0].v[1] == 10.0f, "test_vec vector ADD_LIST failed"); CHECK(test_vec.l[0].v[2] == 10.0f, "test_vec vector ADD_LIST failed"); CHECK(test_vec.l[0].v[3] == 10.0f, "test_vec vector ADD_LIST failed"); Vector inc; VEC_ASSIGN(inc, 1.0f, 1.0f, 1.0f, 1.0f); VEC_ADD(val, val, inc); ADD_LIST(test_vec, val); VEC_ADD(val, val, inc); ADD_LIST(test_vec, val); VEC_ADD(val, val, inc); ADD_LIST(test_vec, val); VEC_ADD(val, val, inc); ADD_LIST(test_vec, val); VEC_ADD(val, val, inc); ADD_LIST(test_vec, val); VEC_ADD(val, val, inc); ADD_LIST(test_vec, val); CHECK(test_vec.l[6].v[0] == 16.0f, "test_vec vector ADD_LIST failed"); CHECK(test_vec.l[6].v[1] == 16.0f, "test_vec vector ADD_LIST failed"); CHECK(test_vec.l[6].v[2] == 16.0f, "test_vec vector ADD_LIST failed"); CHECK(test_vec.l[6].v[3] == 16.0f, "test_vec vector ADD_LIST failed"); CHECK(test_int.cur_size == 7, "test_int vector ADD_LIST failed"); CHECK(test_int.max_size == 10, "test_int vector ADD_LIST failed"); return test_result; }
static DDWORD DemoSky_EngineMessageFn(LPBASECLASS pObject, DDWORD messageID, void *pData, float lData) { DemoSkyWorldModel *pModel; SkyDef def; DVector pos, temp; ObjectCreateStruct *pStruct; HOBJECT hObject; pModel = (DemoSkyWorldModel*)pObject; switch(messageID) { case MID_PRECREATE: { pStruct = (ObjectCreateStruct*)pData; pStruct->m_ObjectType = OT_WORLDMODEL; if( lData == 1.0f ) { g_pServerDE->GetPropVector("SkyDims", &pModel->SkyDims); g_pServerDE->GetPropString("Name", pStruct->m_Filename, MAX_CS_FILENAME_LEN); g_pServerDE->GetPropReal("InnerPercentX", &pModel->InnerPercentX); g_pServerDE->GetPropReal("InnerPercentY", &pModel->InnerPercentY); g_pServerDE->GetPropReal("InnerPercentZ", &pModel->InnerPercentZ); g_pServerDE->GetPropLongInt("Index", &pModel->Index); } else { VEC_INIT( pModel->SkyDims ); pModel->InnerPercentX = 0.1f; pModel->InnerPercentY = 0.1f; pModel->InnerPercentZ = 0.1f; pModel->Index = 0; } break; } case MID_INITIALUPDATE: { // Set the sky box? if(pModel->SkyDims.x != 0.0f && pModel->SkyDims.y != 0.0f && pModel->SkyDims.z != 0.0f) { g_pServerDE->GetObjectPos(pModel->BaseClass.m_hObject, &pos); VEC_SUB(def.m_Min, pos, pModel->SkyDims); VEC_ADD(def.m_Max, pos, pModel->SkyDims); temp.x = pModel->SkyDims.x * pModel->InnerPercentX; temp.y = pModel->SkyDims.y * pModel->InnerPercentY; temp.z = pModel->SkyDims.z * pModel->InnerPercentZ; VEC_SUB(def.m_ViewMin, pos, temp); VEC_ADD(def.m_ViewMax, pos, temp); g_pServerDE->SetSkyDef(&def); } hObject = pModel->BaseClass.m_hObject; g_pServerDE->SetObjectFlags(hObject, g_pServerDE->GetObjectFlags(hObject) | (FLAG_SKYOBJECT|FLAG_FORCEOPTIMIZEOBJECT)); g_pServerDE->AddObjectToSky(pModel->BaseClass.m_hObject, pModel->Index); break; } } return bc_EngineMessageFn(pObject, messageID, pData, lData); }
LTBOOL CBulletTrailFX::Update() { if (!m_hObject || !m_pClientDE) return LTFALSE; LTFLOAT fTime = m_pClientDE->GetTime(); if (m_bFirstUpdate) { // See if we can figure out what color bubbles to make, based on the // container we start in... HLOCALOBJ objList[1]; uint32 dwNum = m_pClientDE->GetPointContainers(&m_vStartPos, objList, 1); if (dwNum > 0 && objList[0]) { uint32 dwUserFlags; m_pClientDE->GetObjectUserFlags(objList[0], &dwUserFlags); if (dwUserFlags & USRFLG_VISIBLE) { uint16 dwCode; if (m_pClientDE->GetContainerCode(objList[0], &dwCode)) { GetLiquidColorRange((ContainerCode)dwCode, &m_vColor1, &m_vColor2); } } } // Move the particle system to the correct position... m_pClientDE->SetObjectPos(m_hObject, &m_vStartPos); m_bFirstUpdate = LTFALSE; m_fStartTime = fTime; m_fLastTime = fTime; VEC_INIT(m_vLastPos); // Find the end position... ClientIntersectQuery iQuery; ClientIntersectInfo iInfo; LTVector vTemp, vEndPoint; VEC_MULSCALAR(vTemp, m_vDir, MAX_TRAIL_LENGTH); VEC_ADD(vEndPoint, m_vStartPos, vTemp); VEC_COPY(iQuery.m_From, m_vStartPos); VEC_COPY(iQuery.m_To, vEndPoint); if (m_pClientDE->IntersectSegment(&iQuery, &iInfo)) { VEC_SUB(vEndPoint, iInfo.m_Point, m_vStartPos); m_fDistance = VEC_MAG(vEndPoint); } if (m_fDistance <= 0.0f || m_fFadeTime <= 0.0f) return LTFALSE; // Calculate the trail velocity... m_fTrailVel = m_fDistance / m_fFadeTime; VEC_MULSCALAR(m_vDir, m_vDir, m_fTrailVel); } // Check to see if we should just wait for last bubble to go away... if (fTime > m_fStartTime + m_fFadeTime) { if (fTime > m_fLastTime + m_fLifeTime) { return LTFALSE; } LTFLOAT fScale = (m_fLifeTime - (fTime - m_fLastTime)) / m_fLifeTime; // m_pClientDE->SetParticleSystemColorScale(m_hObject, fScale); LTFLOAT r, g, b, a; m_pClientDE->GetObjectColor(m_hObject, &r, &g, &b, &a); m_pClientDE->SetObjectColor(m_hObject, r, g, b, fScale); return LTTRUE; } // Create the necessary particles... LTFLOAT fTimeOffset = g_pGameClientShell->GetFrameTime(); // Calculate distance traveled this frame... LTFLOAT fDist = m_fTrailVel * fTimeOffset; if (fDist > m_fDistance) fDist = m_fDistance; m_fDistTraveled += fDist; if (m_fDistTraveled > m_fDistance) { fDist = m_fDistance - (m_fDistTraveled - fDist); if (fDist <= 0.0f) return LTTRUE; } // Calculate number of particles to create... LTFLOAT fNumParticles = fDist * m_fNumParticles / m_fDistance; // Calculate starting bubble position... LTVector vCurPos, vPos, vDelta, vTemp, vDriftVel, vColor; VEC_MULSCALAR(vTemp, m_vDir, fTimeOffset); VEC_ADD(vCurPos, m_vLastPos, vTemp); // What is the range of colors? LTFLOAT fRange = m_vColor2.x - m_vColor1.x; // Fill the distance between the last projectile position, and it's // current position with bubbles... VEC_SUB(vTemp, vCurPos, m_vLastPos); VEC_MULSCALAR(vDelta, vTemp, 1.0f/fNumParticles); VEC_COPY(vPos, m_vLastPos); LTFLOAT fLifeTime = 100.0f; LTFLOAT fOffset = 0.0f; LTVector vDriftOffset; VEC_SET(vDriftOffset, 0.0f, 0.0f, 0.0f); int nNumParticles = GetNumParticles((int)fNumParticles); for (int i=0; i < nNumParticles; i++) { // Build the individual bubbless... for (int j=0; j < 1; j++) { VEC_COPY(vTemp, vPos); VEC_SET(vDriftVel, 0.0f, GetRandom(5.0f, 6.0f), 0.0f); vTemp.x += GetRandom(-fOffset, fOffset); vTemp.y += GetRandom(-fOffset, fOffset); vTemp.z += GetRandom(-fOffset, fOffset); GetRandomColorInRange(vColor); m_pClientDE->AddParticle(m_hObject, &vTemp, &vDriftVel, &vColor, fLifeTime); } VEC_ADD(vPos, vPos, vDelta); } VEC_COPY(m_vLastPos, vCurPos); m_fLastTime = fTime; return LTTRUE; }
DBOOL CSmokePuffFX::Update() { if(!m_hObject || !m_pClientDE) return DFALSE; DFLOAT fTime = m_pClientDE->GetTime(); if (m_fStartTime < 0) { m_fStartTime = m_fLastTime = fTime; } // Make sure we update our position relative to the server object (if the // server object is valid)... if (m_hServerObject) { DVector vServPos; m_pClientDE->GetObjectPos(m_hServerObject, &vServPos); m_pClientDE->SetObjectPos(m_hObject, &vServPos); } // Check to see if we should just wait for last smoke puff to go away... DFLOAT fTimeDelta = fTime - m_fStartTime; if (fTimeDelta > m_fLifeTime) { return DFALSE; } if (m_fDriftDeceleration) { DFLOAT fDecel = 1 - m_pClientDE->GetFrameTime() * m_fDriftDeceleration; VEC_MULSCALAR(m_vMinDriftVel, m_vMinDriftVel, fDecel); VEC_MULSCALAR(m_vMaxDriftVel, m_vMaxDriftVel, fDecel); } DFLOAT fScale = ((m_fLifeTime - fTimeDelta) / m_fLifeTime) * m_fMaxAlpha; // Adjust the alpha DFLOAT r, g, b, a; m_pClientDE->GetObjectColor(m_hObject, &r, &g, &b, &a); m_pClientDE->SetObjectColor(m_hObject, r, g, b, fScale); // See if it is time to add some more smoke... if (fTime > m_fLastTime + m_fParticleCreateDelta && (fTimeDelta < m_fCreateLifetime) ) { DVector vDriftVel, vColor, vPos; // What is the range of colors? DFLOAT fRange = m_vColor2.x - m_vColor1.x; // Build the individual smoke puffs... for (DDWORD j=0; j < m_nNumParticles; j++) { DFLOAT fX, fY, fAngle, fRadius; fAngle = GetRandom(-MATH_PI, MATH_PI); fRadius = GetRandom(0.0f, m_fVolumeRadius); fX = fRadius * (DFLOAT)cos(fAngle); fY = fRadius * (DFLOAT)sin(fAngle); VEC_SET(vPos, fX, -2.0f, fY); VEC_SET(vDriftVel, GetRandom(m_vMinDriftVel.x, m_vMaxDriftVel.x), GetRandom(m_vMinDriftVel.y, m_vMaxDriftVel.y), GetRandom(m_vMinDriftVel.z, m_vMaxDriftVel.z)); if (!m_bIgnoreWind) { VEC_ADD(vDriftVel, vDriftVel, g_vWorldWindVel); } DFLOAT fOffset = GetRandom(m_vColor1.x, m_vColor2.x); DFLOAT fPercent = 1.0f; if (fRange > 0.01) { fPercent = fOffset / fRange; } vColor.x = m_vColor1.x + fOffset; fOffset = fPercent * (m_vColor2.y - m_vColor1.y); vColor.y = m_vColor1.y + fOffset; fOffset = fPercent * (m_vColor2.z - m_vColor1.z); vColor.z = m_vColor1.z + fOffset; DFLOAT fLifeTime = GetRandom(m_fMinParticleLife, m_fMaxParticleLife); m_pClientDE->AddParticle(m_hObject, &vPos, &vDriftVel, &vColor, fLifeTime); } m_fLastTime = fTime; } return DTRUE; }
LTBOOL CSmokeFX::Update() { if (!m_hObject || !m_pClientDE ) return LTFALSE; if( g_pGameClientShell->IsServerPaused() ) { g_pCommonLT->SetObjectFlags(m_hObject, OFT_Flags, FLAG_PAUSED, FLAG_PAUSED); return LTTRUE; } //make sure we aren't paused g_pCommonLT->SetObjectFlags(m_hObject, OFT_Flags, 0, FLAG_PAUSED); LTFLOAT fFrameTime = m_pClientDE->GetFrameTime(); m_fElapsedTime += fFrameTime; m_fElapsedEmissionTime += fFrameTime; // Hide/show the particle system if necessary... if (m_hServerObject) { uint32 dwUserFlags; g_pCommonLT->GetObjectFlags(m_hServerObject, OFT_User, dwUserFlags); if (!(dwUserFlags & USRFLG_VISIBLE)) { uint32 dwFlags; g_pCommonLT->GetObjectFlags(m_hObject, OFT_Flags, dwFlags); // Once last puff as disappeared, hide the system (no new puffs // will be added...) if (dwFlags & FLAG_VISIBLE) { if (m_fElapsedEmissionTime > m_fMaxParticleLife) { g_pCommonLT->SetObjectFlags(m_hObject, OFT_Flags, 0, FLAG_VISIBLE); } } else { m_fElapsedEmissionTime = 0.0f; } return LTTRUE; } else { g_pCommonLT->SetObjectFlags(m_hObject, OFT_Flags, FLAG_VISIBLE, FLAG_VISIBLE); } } // Check to see if we should just wait for last smoke puff to go away... if (m_fElapsedTime > m_fLifeTime) { if (m_fElapsedEmissionTime > m_fMaxParticleLife) { return LTFALSE; } return LTTRUE; } // See if it is time to add some more smoke... if (m_fElapsedEmissionTime >= m_fParticleCreateDelta) { LTVector vDriftVel, vColor, vPos; // What is the range of colors? LTFLOAT fRange = m_vColor2.x - m_vColor1.x; // Determine how many particles to add... int nNumParticles = GetNumParticles(m_nNumParticles); // Build the individual smoke puffs... for (int j=0; j < nNumParticles; j++) { VEC_SET(vPos, GetRandom(-m_fVolumeRadius, m_fVolumeRadius), -2.0f, GetRandom(-m_fVolumeRadius, m_fVolumeRadius)); VEC_SET(vDriftVel, GetRandom(m_vMinDriftVel.x, m_vMaxDriftVel.x), GetRandom(m_vMinDriftVel.y, m_vMaxDriftVel.y), GetRandom(m_vMinDriftVel.z, m_vMaxDriftVel.z)); if (!m_bIgnoreWind) { VEC_ADD(vDriftVel, vDriftVel, g_vWorldWindVel); } GetRandomColorInRange(vColor); LTFLOAT fLifeTime = GetRandom(m_fMinParticleLife, m_fMaxParticleLife); vDriftVel -= (m_vVel * 0.1f); m_pClientDE->AddParticle(m_hObject, &vPos, &vDriftVel, &vColor, fLifeTime); } m_fElapsedEmissionTime = 0.0f; } return CBaseParticleSystemFX::Update(); }
static DDWORD SkyPointer_EngineMessageFn(LPBASECLASS pObject, DDWORD messageID, void *pData, float lData) { SkyPointer *pModel; SkyDef def; DVector pos, temp; ObjectCreateStruct *pStruct; ObjectList *pList; HOBJECT hObject; pModel = (SkyPointer*)pObject; switch(messageID) { case MID_PRECREATE: { pStruct = (ObjectCreateStruct*)pData; pStruct->m_ObjectType = OT_NORMAL; pModel->m_hObject = 0; if( lData == 1.0f ) { g_pServerDE->GetPropVector("SkyDims", &pModel->SkyDims); g_pServerDE->GetPropString("Name", pStruct->m_Filename, MAX_CS_FILENAME_LEN); g_pServerDE->GetPropString("SkyObjectName", pModel->m_ObjectName, sizeof(pModel->m_ObjectName)-1); g_pServerDE->GetPropReal("InnerPercentX", &pModel->InnerPercentX); g_pServerDE->GetPropReal("InnerPercentY", &pModel->InnerPercentY); g_pServerDE->GetPropReal("InnerPercentZ", &pModel->InnerPercentZ); g_pServerDE->GetPropLongInt("Index", &pModel->Index); } else { pModel->m_ObjectName[0] = 0; VEC_INIT( pModel->SkyDims ); pModel->InnerPercentX = 0.1f; pModel->InnerPercentY = 0.1f; pModel->InnerPercentZ = 0.1f; pModel->Index = 0; } break; } case MID_INITIALUPDATE: { // Set the sky box? if(pModel->SkyDims.x != 0.0f && pModel->SkyDims.y != 0.0f && pModel->SkyDims.z != 0.0f) { g_pServerDE->GetObjectPos(pModel->BaseClass.m_hObject, &pos); VEC_SUB(def.m_Min, pos, pModel->SkyDims); VEC_ADD(def.m_Max, pos, pModel->SkyDims); temp.x = pModel->SkyDims.x * pModel->InnerPercentX; temp.y = pModel->SkyDims.y * pModel->InnerPercentY; temp.z = pModel->SkyDims.z * pModel->InnerPercentZ; VEC_SUB(def.m_ViewMin, pos, temp); VEC_ADD(def.m_ViewMax, pos, temp); g_pServerDE->SetSkyDef(&def); } g_pServerDE->SetNextUpdate(pModel->BaseClass.m_hObject, 0.001f); break; } case MID_UPDATE: { // Add the first object to the sky. pList = g_pServerDE->FindNamedObjects(pModel->m_ObjectName); if(pList && pList->m_pFirstLink) { hObject = pList->m_pFirstLink->m_hObject; g_pServerDE->AddObjectToSky(hObject, pModel->Index); g_pServerDE->SetObjectFlags(hObject, g_pServerDE->GetObjectFlags(hObject) | (FLAG_SKYOBJECT|FLAG_FORCEOPTIMIZEOBJECT)); g_pServerDE->RelinquishList(pList); } g_pServerDE->RemoveObject(pModel->BaseClass.m_hObject); break; } } return bc_EngineMessageFn(pObject, messageID, pData, lData); }
DBOOL CMarkSFX::CreateObject(CClientDE *pClientDE) { if (!CSpecialFX::CreateObject(pClientDE)) return DFALSE; CSFXMgr* psfxMgr = g_pBloodClientShell->GetSFXMgr(); if (!psfxMgr) return DFALSE; // Before we create a new buillet hole see if there is already another // bullet hole close by that we could use instead... CSpecialFXList* pList = psfxMgr->GetBulletHoleFXList(); if (!pList) return DFALSE; int nNumBulletHoles = pList->GetSize(); HOBJECT hMoveObj = DNULL; HOBJECT hObj = DNULL; DFLOAT fClosestMarkDist = REGION_DIAMETER; DBYTE nNumInRegion = 0; DVector vPos; for (int i=0; i < nNumBulletHoles; i++) { if ((*pList)[i]) { hObj = (*pList)[i]->GetObject(); if (hObj) { pClientDE->GetObjectPos(hObj, &vPos); DFLOAT fDist = VEC_DISTSQR(vPos, m_Pos); if (fDist < REGION_DIAMETER) { if (fDist < fClosestMarkDist) { fClosestMarkDist = fDist; hMoveObj = hObj; } if (++nNumInRegion > MAX_MARKS_IN_REGION) { // Just move this bullet-hole to the correct pos, and // remove thyself... pClientDE->SetObjectPos(hMoveObj, &m_Pos); return DFALSE; } } } } } // Setup the mark... ObjectCreateStruct createStruct; INIT_OBJECTCREATESTRUCT(createStruct); createStruct.m_ObjectType = OT_SPRITE; _mbscpy((unsigned char*)createStruct.m_Filename, (const unsigned char*)m_pClientDE->GetStringData( m_hstrSprite )); createStruct.m_Flags = FLAG_VISIBLE | FLAG_ROTATEABLESPRITE; VEC_COPY(createStruct.m_Pos, m_Pos); ROT_COPY( createStruct.m_Rotation, m_Rotation ); m_hObject = pClientDE->CreateObject(&createStruct); m_pClientDE->SetObjectScale(m_hObject, &m_vScale); // See what it hit DVector vU, vR; pClientDE->GetRotationVectors(&m_Rotation, &vU, &vR, &m_vForward); ClientIntersectQuery iq; ClientIntersectInfo ii; iq.m_Flags = INTERSECT_OBJECTS | INTERSECT_HPOLY; VEC_COPY(iq.m_From, vPos); // Get start point at the last known position. VEC_MULSCALAR(iq.m_To, m_vForward, -1.0f); VEC_ADD(iq.m_To, iq.m_To, iq.m_From); // Get destination point slightly past where we should be // Hit something! try to clip against it. (since this is only being used for bullet marks, if (pClientDE->IntersectSegment(&iq, &ii)) { HPOLY hPoly = ii.m_hPoly; pClientDE->ClipSprite(m_hObject, hPoly); } m_pClientDE->SetObjectColor(m_hObject, 0.1f, 0.1f, 0.1f, 1.0f); return DTRUE; }
LTBOOL CBaseParticleSystemFX::Update() { if (!CSpecialFX::Update() || !m_hObject || !m_pClientDE) return LTFALSE; // See if we should rotate this bad-boy... if (m_vRotVel.x != 0.0f || m_vRotVel.y != 0.0f || m_vRotVel.z != 0.0f) { LTFLOAT fDelta = g_pGameClientShell->GetFrameTime(); LTRotation rRot; m_pClientDE->GetObjectRotation(m_hObject, &rRot); LTVector vTemp; VEC_MULSCALAR(vTemp, m_vRotVel, fDelta); VEC_ADD(m_vRotAmount, m_vRotAmount, vTemp); if (m_vRotVel.x != 0.0f) m_pClientDE->EulerRotateX(&rRot, m_vRotAmount.x); if (m_vRotVel.y != 0.0f) m_pClientDE->EulerRotateY(&rRot, m_vRotAmount.y); if (m_vRotVel.z != 0.0f) m_pClientDE->EulerRotateZ(&rRot, m_vRotAmount.z); m_pClientDE->SetObjectRotation(m_hObject, &rRot); } // Update each particles scale / alpha if necessary... LTParticle *pCur, *pTail; if (m_basecs.bAdjustParticleScale || m_basecs.bAdjustParticleAlpha) { if (m_pClientDE->GetParticles(m_hObject, &pCur, &pTail)) { LTFLOAT fLifetime = 0.0f, fTotalLifetime = 0.0f; LTFLOAT fAlphaRange = m_basecs.fEndParticleAlpha - m_basecs.fStartParticleAlpha; LTFLOAT fScaleRange = m_basecs.fEndParticleScale - m_basecs.fStartParticleScale; LTVector vColorRange = m_vColor2 - m_vColor1; while (pCur && pCur != pTail) { m_pClientDE->GetParticleLifetime(m_hObject, pCur, fLifetime); m_pClientDE->GetParticleTotalLifetime(m_hObject, pCur, fTotalLifetime); if (fLifetime > 0.0f && fTotalLifetime > 0.0f) { LTFLOAT fLifePercent = 1.0f - (fLifetime / fTotalLifetime); // Adjust scale... if (m_basecs.bAdjustParticleScale) { pCur->m_Size = m_fRadius * (m_basecs.fStartParticleScale + (fScaleRange * fLifePercent)); } // Adjust alpha... if (m_basecs.bAdjustParticleAlpha) { pCur->m_Alpha = m_basecs.fStartParticleAlpha + (fAlphaRange * fLifePercent); } } pCur = pCur->m_pNext; } } } // Make sure we update our position relative to the server object // (if the server object is valid and the client isn't controling // the particle system pos)... if (m_hServerObject && !m_basecs.bClientControlsPos) { LTVector vNewPos; m_pClientDE->GetObjectPos(m_hServerObject, &vNewPos); vNewPos += m_vPosOffset; m_pClientDE->SetObjectPos(m_hObject, &vNewPos); } return LTTRUE; }
void CFolderWeaponControls::CreateModelSFX() { // no model = no SFX if (!strlen(m_szModel)) return; HOBJECT hCamera = g_pGameClientShell->GetInterfaceCamera(); if (!hCamera) return; BSCREATESTRUCT bcs; LTVector vPos, vU, vR, vF, vTemp, vScale(1.0f,1.0f,1.0f); LTRotation rRot; g_pLTClient->GetObjectPos(hCamera, &vPos); g_pLTClient->GetObjectRotation(hCamera, &rRot); g_pLTClient->GetRotationVectors(&rRot, &vU, &vR, &vF); g_pLTClient->RotateAroundAxis(&rRot, &vU, MATH_HALFPI); g_pLTClient->RotateAroundAxis(&rRot, &vR, -0.3f); VEC_MULSCALAR(vScale, vScale, m_fScale); LTVector vModPos = g_pLayoutMgr->GetFolderCustomVector((eFolderID)m_nFolderID,"ModelPos"); VEC_ADD(vModPos,vModPos,m_vOffset); VEC_MULSCALAR(vTemp, vF, vModPos.z); VEC_MULSCALAR(vTemp, vTemp, g_pInterfaceResMgr->GetXRatio()); VEC_ADD(vPos, vPos, vTemp); VEC_MULSCALAR(vTemp, vR, vModPos.x); VEC_ADD(vPos, vPos, vTemp); VEC_MULSCALAR(vTemp, vU, vModPos.y); VEC_ADD(vPos, vPos, vTemp); VEC_COPY(bcs.vPos, vPos); bcs.rRot = rRot; VEC_COPY(bcs.vInitialScale, vScale); VEC_COPY(bcs.vFinalScale, vScale); VEC_SET(bcs.vInitialColor, 1.0f, 1.0f, 1.0f); VEC_SET(bcs.vFinalColor, 1.0f, 1.0f, 1.0f); bcs.bUseUserColors = LTTRUE; bcs.pFilename = m_szModel; bcs.pSkin = m_szSkin; bcs.dwFlags = FLAG_VISIBLE | FLAG_FOGDISABLE | FLAG_NOLIGHT; bcs.nType = OT_MODEL; bcs.fInitialAlpha = 1.0f; bcs.fFinalAlpha = 1.0f; bcs.fLifeTime = 1000000.0f; if (m_ModelSFX.Init(&bcs)) { m_ModelSFX.CreateObject(g_pLTClient); g_pInterfaceMgr->AddInterfaceSFX(&m_ModelSFX, IFX_NORMAL); m_fSFXRot = g_pLayoutMgr->GetFolderCustomFloat((eFolderID)m_nFolderID,"ModelRotSpeed"); } }
DDWORD BugAI::EngineMessageFn(DDWORD messageID, void *pData, DFLOAT fData) { switch(messageID) { case MID_PRECREATE: { // Need to call base class to have the object name read in before // we call PostPropRead() DDWORD dwRet = AI_Mgr::EngineMessageFn(messageID, pData, fData); if (fData == 1.0) AI_Mgr::ReadProp((ObjectCreateStruct*)pData); // inside BaseCharacter PostPropRead((ObjectCreateStruct*)pData); return dwRet; } break; case MID_INITIALUPDATE: { InitialUpdate((DVector *)pData); break; } case MID_UPDATE: { CServerDE* pServerDE = GetServerDE(); if (!pServerDE) return 0; //gotta keep the bug stuck to whatever surface it is on DRotation rRot; DVector vU,vR,vF,vVel,vPos; pServerDE->GetObjectPos(m_hObject,&vPos); pServerDE->GetObjectRotation(m_hObject,&rRot); pServerDE->GetRotationVectors(&rRot,&vU,&vR,&vF); VEC_MULSCALAR(vVel,vU,-15.0f); Move(vVel, MATH_EPSILON); //check if there is something below, if not rotate IntersectQuery IQuery; IntersectInfo ii; IQuery.m_Flags = INTERSECT_OBJECTS; IQuery.m_FilterFn = DNULL; DVector vTemp; VEC_MULSCALAR(vTemp,vU,-2.0f); VEC_COPY(IQuery.m_From,vPos); VEC_ADD(IQuery.m_To,IQuery.m_From,vTemp); if(pServerDE->IntersectSegment(&IQuery, &ii)) { DRotation rRot; DVector vDown; VEC_MULSCALAR(vDown,vU,-1.0f); pServerDE->AlignRotation(&rRot,&vDown,&vF); pServerDE->SetObjectRotation(m_hObject,&rRot); } } break; default : break; } return AI_Mgr::EngineMessageFn(messageID, pData, fData); }
void CParticleExplosionFX::AddParticles(MovingObject* pObject) { if (!m_hObject || !m_pClientDE || !pObject || pObject->m_PhysicsFlags & MO_RESTING) return; LTFLOAT fTime = m_pClientDE->GetTime(); LTVector vCurPos, vLastPos, vPos, vDelta, vTemp, vDriftVel, vColor; VEC_COPY(vCurPos, pObject->m_Pos); VEC_COPY(vLastPos, pObject->m_LastPos); // Calculate Particle puff positions... // Current position is relative to the particle system's postion (i.e., // each puff of Particle is some distance away from the particle system's // position)... VEC_SUB(vCurPos, vCurPos, m_vPos); VEC_SUB(vLastPos, vLastPos, m_vPos); // How long has it been since the last Particle puff? LTFLOAT fTimeOffset = fTime - m_fLastTime; // Fill the distance between the last projectile position, and it's // current position with Particle puffs... VEC_SUB(vTemp, vCurPos, vLastPos); VEC_MULSCALAR(vDelta, vTemp, 1.0f/LTFLOAT(m_nNumSteps)); VEC_COPY(vPos, vLastPos); LTFLOAT fCurLifeTime = 10.0f; LTFLOAT fLifeTimeOffset = fTimeOffset / LTFLOAT(m_nNumSteps); LTFLOAT fOffset = 0.5f; if (m_bSmall) { fOffset /= 2.0f; } for (int i=0; i < m_nNumSteps; i++) { // Build the individual Particle puffs... for (int j=0; j < m_nNumPerPuff; j++) { VEC_COPY(vTemp, vPos); VEC_SET(vDriftVel, GetRandom(m_vMinDriftOffset.x, m_vMaxDriftOffset.x), GetRandom(m_vMinDriftOffset.y, m_vMaxDriftOffset.y), GetRandom(m_vMinDriftOffset.z, m_vMaxDriftOffset.z)); if (!m_bIgnoreWind) { vDriftVel.x += g_vWorldWindVel.x; vDriftVel.y += g_vWorldWindVel.y; vDriftVel.z += g_vWorldWindVel.z; } vTemp.x += GetRandom(-fOffset, fOffset); vTemp.y += GetRandom(-fOffset, fOffset); vTemp.z += GetRandom(-fOffset, fOffset); GetRandomColorInRange(vColor); m_pClientDE->AddParticle(m_hObject, &vTemp, &vDriftVel, &vColor, fCurLifeTime); } VEC_ADD(vPos, vPos, vDelta); fCurLifeTime += fLifeTimeOffset; } }
LTBOOL CParticleExplosionFX::CreateObject(ILTClient *pClientDE) { LTBOOL bRet = CBaseParticleSystemFX::CreateObject(pClientDE); if (!bRet) return bRet; // Initialize the emmitters velocity ranges based on our rotation... LTVector vVelMin, vVelMax, vTemp, vU, vR, vF; VEC_SET(vVelMin, 1.0f, 1.0f, 1.0f); VEC_SET(vVelMax, 1.0f, 1.0f, 1.0f); m_pClientDE->Common()->GetRotationVectors(m_rSurfaceRot, vU, vR, vF); if (vF.y <= -0.95f || vF.y >= 0.95f) { vF.y = vF.y > 0.0f ? 1.0f : -1.0f; VEC_SET(vR, 1.0f, 0.0f, 0.0f); VEC_SET(vU, 0.0f, 0.0f, 1.0f); } else if (vF.x <= -0.95f || vF.x >= 0.95f) { vF.x = vF.x > 0.0f ? 1.0f : -1.0f; VEC_SET(vR, 0.0f, 1.0f, 0.0f); VEC_SET(vU, 0.0f, 0.0f, 1.0f); } else if (vF.z <= -0.95f || vF.z >= 0.95f) { vF.z = vF.z > 0.0f ? 1.0f : -1.0f; VEC_SET(vR, 1.0f, 0.0f, 0.0f); VEC_SET(vU, 0.0f, 1.0f, 0.0f); } VEC_MULSCALAR(vVelMin, vF, m_vMinVel.y); VEC_MULSCALAR(vVelMax, vF, m_vMaxVel.y); VEC_MULSCALAR(vTemp, vR, m_vMinVel.x); VEC_ADD(vVelMin, vVelMin, vTemp); VEC_MULSCALAR(vTemp, vR, m_vMaxVel.x); VEC_ADD(vVelMax, vVelMax, vTemp); VEC_MULSCALAR(vTemp, vU, m_vMinVel.z); VEC_ADD(vVelMin, vVelMin, vTemp); VEC_MULSCALAR(vTemp, vU, m_vMaxVel.z); VEC_ADD(vVelMax, vVelMax, vTemp); // Initialize our emmitters... LTVector vStartVel; for (int i=0; i < m_nNumEmmitters; i++) { if (m_bCreateDebris) { m_hDebris[i] = CreateDebris(); } m_ActiveEmmitters[i] = LTTRUE; m_BounceCount[i] = 2; VEC_SET(vStartVel, GetRandom(vVelMin.x, vVelMax.x), GetRandom(vVelMin.y, vVelMax.y), GetRandom(vVelMin.z, vVelMax.z)); InitMovingObject(&(m_Emmitters[i]), &m_vPos, &vStartVel); m_Emmitters[i].m_PhysicsFlags |= m_nEmmitterFlags; } return bRet; }
void M2M(FmmvHandle *FMMV, Box *box) { int p = FMMV->pM; int len0 = (p+1)*(p+1); int len = (p+1)*(p+2); int *P_RT = FMMV->P_MRT; int *P_riri2rrii = FMMV->P_Mriri2rrii; _FLOAT_ x1[(FMM_P_MAX+1)*(FMM_P_MAX+2)]; _FLOAT_ x2[(FMM_P_MAX+1)*(FMM_P_MAX+2)]; _FLOAT_ xx[(FMM_P_MAX+1)*(FMM_P_MAX+2)]; if (!isSource(box)) return; if (isSource(box->child[SWD])&&box->child[SWD]->M) { Rz_pi4(p, box->child[SWD]->M, x2); perm(len0, P_riri2rrii, x2, x1); Ry(p, FMMV->Ry_pi_minus_theta, x1, x2); perm(len0, P_RT, x2, x1); Tz_M2M(FMMV, x1); perm_inv(len0, P_RT, x1, xx); if (isSource(box->child[NEU])&&box->child[NEU]->M) { Rz_pi4(p, box->child[NEU]->M, x2); perm(len0, P_riri2rrii, x2, x1); Ry(p, FMMV->Ry_minus_theta, x1, x2); perm(len0, P_RT, x2, x1); Tz_M2M(FMMV, x1); perm_inv(len0, P_RT, x1, x2); Ry_pi(p, x2); VEC_ADD(len, x2, xx, xx); } Ry(p, FMMV->Ry_minus_pi_minus_theta, xx, x1); perm_inv(len0, P_riri2rrii, x1, x2); Rz_minus_pi4(p, x2, x1); box->M = VEC_ADD2(FMMV, len, x1, box->M); } else if (isSource(box->child[NEU])&&box->child[NEU]->M) { Rz_pi4(p, box->child[NEU]->M, x2); perm(len0, P_riri2rrii, x2, x1); Ry(p, FMMV->Ry_minus_theta,x1, x2); perm(len0, P_RT, x2, x1); Tz_M2M(FMMV, x1); perm_inv(len0, P_RT, x1, x2); Ry(p, FMMV->Ry_theta, x2, x1); perm_inv(len0, P_riri2rrii, x1, x2); Rz_minus_pi4(p, x2, x1); box->M = VEC_ADD2(FMMV, len, x1, box->M); } if (isSource(box->child[NWD])&&box->child[NWD]->M) { Rz_minus_pi4(p, box->child[NWD]->M, x2); perm(len0, P_riri2rrii, x2, x1); Ry(p, FMMV->Ry_pi_minus_theta, x1, x2); perm(len0, P_RT, x2, x1); Tz_M2M(FMMV, x1); perm_inv(len0, P_RT, x1, xx); if (isSource(box->child[SEU])&&box->child[SEU]->M) { Rz_minus_pi4(p, box->child[SEU]->M, x2); perm(len0, P_riri2rrii, x2, x1); Ry(p, FMMV->Ry_minus_theta, x1, x2); perm(len0, P_RT, x2, x1); Tz_M2M(FMMV, x1); perm_inv(len0, P_RT, x1, x2); Ry_pi(p, x2); VEC_ADD(len, x2, xx, xx); } Ry(p, FMMV->Ry_minus_pi_minus_theta, xx, x1); perm_inv(len0, P_riri2rrii, x1, x2); Rz_pi4(p, x2, x1); box->M = VEC_ADD2(FMMV, len, x1, box->M); } else if (isSource(box->child[SEU])&&box->child[SEU]->M) { Rz_minus_pi4(p, box->child[SEU]->M, x2); perm(len0, P_riri2rrii, x2, x1); Ry(p, FMMV->Ry_minus_theta, x1, x2); perm(len0, P_RT, x2, x1); Tz_M2M(FMMV, x1); perm_inv(len0, P_RT, x1, x2); Ry(p, FMMV->Ry_theta, x2, x1); perm_inv(len0, P_riri2rrii, x1, x2); Rz_pi4(p, x2, x1); box->M = VEC_ADD2(FMMV, len, x1, box->M); } if (isSource(box->child[SED])&&box->child[SED]->M) { Rz_3pi4(p, box->child[SED]->M, x2); perm(len0, P_riri2rrii, x2, x1); Ry(p, FMMV->Ry_pi_minus_theta, x1, x2); perm(len0, P_RT, x2, x1); Tz_M2M(FMMV, x1); perm_inv(len0, P_RT, x1, xx); if (isSource(box->child[NWU])&&box->child[NWU]->M) { Rz_3pi4(p, box->child[NWU]->M, x2); perm(len0, P_riri2rrii, x2, x1); Ry(p, FMMV->Ry_minus_theta, x1, x2); perm(len0, P_RT, x2, x1); Tz_M2M(FMMV, x1); perm_inv(len0, P_RT, x1, x2); Ry_pi(p, x2); VEC_ADD(len, x2, xx, xx); } Ry(p, FMMV->Ry_minus_pi_minus_theta, xx, x1); perm_inv(len0, P_riri2rrii, x1, x2); Rz_minus_3pi4(p, x2, x1); box->M = VEC_ADD2(FMMV, len, x1, box->M); } else if (isSource(box->child[NWU])&&box->child[NWU]->M) { Rz_3pi4(p, box->child[NWU]->M, x2); perm(len0, P_riri2rrii, x2, x1); Ry(p, FMMV->Ry_minus_theta, x1, x2); perm(len0, P_RT, x2, x1); Tz_M2M(FMMV, x1); perm_inv(len0, P_RT, x1, x2); Ry(p, FMMV->Ry_theta, x2, x1); perm_inv(len0, P_riri2rrii, x1, x2); Rz_minus_3pi4(p, x2, x1); box->M = VEC_ADD2(FMMV, len, x1, box->M); } if (isSource(box->child[NED])&&box->child[NED]->M) { Rz_minus_3pi4(p, box->child[NED]->M, x2); perm(len0, P_riri2rrii, x2, x1); Ry(p, FMMV->Ry_pi_minus_theta, x1, x2); perm(len0, P_RT, x2, x1); Tz_M2M(FMMV, x1); perm_inv(len0, P_RT, x1, xx); if (isSource(box->child[SWU])&&box->child[SWU]->M) { Rz_minus_3pi4(p, box->child[SWU]->M, x2); perm(len0, P_riri2rrii, x2, x1); Ry(p, FMMV->Ry_minus_theta, x1, x2); perm(len0, P_RT, x2, x1); Tz_M2M(FMMV, x1); perm_inv(len0, P_RT, x1, x2); Ry_pi(p, x2); VEC_ADD(len, x2, xx, xx); } Ry(p, FMMV->Ry_minus_pi_minus_theta, xx, x1); perm_inv(len0, P_riri2rrii, x1, x2); Rz_3pi4(p, x2, x1); box->M = VEC_ADD2(FMMV, len, x1, box->M); } else if (isSource(box->child[SWU])&&box->child[SWU]->M) { Rz_minus_3pi4(p, box->child[SWU]->M, x2); perm(len0, P_riri2rrii, x2, x1); Ry(p, FMMV->Ry_minus_theta, x1, x2); perm(len0, P_RT, x2, x1); Tz_M2M(FMMV, x1); perm_inv(len0, P_RT, x1, x2); Ry(p, FMMV->Ry_theta, x2, x1); perm_inv(len0, P_riri2rrii, x1, x2); Rz_3pi4(p, x2, x1); box->M = VEC_ADD2(FMMV, len, x1, box->M); } }
LTBOOL CSmokeFX::Update() { if(!m_hObject || !m_pClientDE) return LTFALSE; LTFLOAT fTime = m_pClientDE->GetTime(); if (m_fStartTime < 0) { m_fStartTime = m_fLastTime = fTime; } // Make sure we update our position relative to the server object (if the // server object is valid)... if (m_hServerObject) { LTVector vServPos; m_pClientDE->GetObjectPos(m_hServerObject, &vServPos); m_pClientDE->SetObjectPos(m_hObject, &vServPos); } // Check to see if we should just wait for last smoke puff to go away... if (fTime > m_fStartTime + m_fLifeTime) { if (fTime > m_fLastTime + m_fMaxParticleLife) { return LTFALSE; } return LTTRUE; } // See if it is time to add some more smoke... if (fTime > m_fLastTime + m_fParticleCreateDelta) { LTVector vDriftVel, vColor, vPos; // What is the range of colors? LTFLOAT fRange = m_vColor2.x - m_vColor1.x; // Build the individual smoke puffs... for (uint32 j=0; j < m_nNumParticles; j++) { VEC_SET(vPos, GetRandom(-m_fVolumeRadius, m_fVolumeRadius), -2.0f, GetRandom(-m_fVolumeRadius, m_fVolumeRadius)); VEC_SET(vDriftVel, GetRandom(m_vMinDriftVel.x, m_vMaxDriftVel.x), GetRandom(m_vMinDriftVel.y, m_vMaxDriftVel.y), GetRandom(m_vMinDriftVel.z, m_vMaxDriftVel.z)); if (!m_bIgnoreWind) { VEC_ADD(vDriftVel, vDriftVel, g_vWorldWindVel); } GetRandomColorInRange(vColor); LTFLOAT fLifeTime = GetRandom(m_fMinParticleLife, m_fMaxParticleLife); m_pClientDE->AddParticle(m_hObject, &vPos, &vDriftVel, &vColor, fLifeTime); } m_fLastTime = fTime; } return LTTRUE; }